Post by: Martin Dreyer
Posted on: 8/23/2015 6:58:00 PM
Description: As term sets become increasingly interrelated, their design can benefit from formal data design thinking.
IntroductionTerm sets often start out their lives with an isolated purpose but, before we know it, we have multiple areas of the organization depending on them. It is often only after they have taken on their enterprise role that the cracks in their design start to show. By that stage a lot of content is tied to them and that can complicate re-organization.Having arrived at that point more often than I'd like, with term sets that re-use from other term sets, I've wondered whether we could get more scientific about term set design and see red flags earlier. This post proposes that analysing the cardinalities in the domain model can reveal at least one such red flag.The outcome in a nutshellImplement a one-to-one relationship as a (reversible) third composite term setImplement a one-to-many relationship as a (non-reversible) third composite term setGenerally, avoid implementing a many-to-many relationship as a third composite term setThe first two are trivial but lay a foundation for talking about the third, which highlights an anti-pattern.Single IdentityIt will be assumed that you’re already following a practice of establishing elementary base term sets and then reusing from those, uni-directionally, into composite term sets, as discussed in
Good Practice Update Single Identity in Taxonomies. The principle there is you don’t want terms with the same meaning being duplicated with different identities. Rather define them as simple, uncontroversial components in one place and then re-use those building blocks in other arrangements to address the various perspectives the organization needs.Start with a domain modelConstructing a domain model is an important starting point. This is not a technical model but a conceptual model of the real world, covering those things that are relevant to the current scope. If term sets are to fit the world naturally, they must be based on a model that properly describes the real world. Clear definitions are essential since they will help ensure that base term sets are constrained to single, unambiguous concepts. Unconscious mixing of concepts leads to downstream problems.The following will serve as a sample domain model for this post.
In case you're unfamiliar with the crow’s foot notation here is how it should be read. The examples have been chosen so as to cover the three main cardinality types.One-to-many (1N)A Geopolitical Location contains zero or more SitesA Site is located in one and only one Geopolitical LocationOne-to-one (11)A site has one and only one General ManagerA General Manager manages one and only one SiteMany-to-many (MN)A Site is operated by one or more Business UnitsA Business Unit operates at one or more SitesThese relationships
will differ across organizations. Perhaps in your business a Site is operated by one and only one Business Unit.
The data model will have a direct impact on how your term sets are structured, so it’s important to ensure that it depicts your domain accurately. My argument is that the presence of any many-to-many relationship represents a red flag.With a domain model defined, we'll now move on to the corresponding term set patterns. Pattern A Implement a one-to-one relationship as a (reversible) third composite term set11 relationsips are straightforward to implement.If there is a need to represent the combination of two entities then introduce a third term set which corresponds to the associative entity between the first two entities. Re-use terms from the two base term sets into the composite one. One site (such as Calcutta Operations) has one and only one general manager (Sam Govender).
Since this relationship is symmetrical, the term set structure can be reversed. General Managers may be placed beneath Sites or Sites beneath General Managers - whatever suits the purpose. Resist the urge to get away with only two term sets. Keeping the base term sets elementary is more scalable since they could be arranged into a variety of other combinations in other term sets.This is pretty obvious. Let's move on to the next pattern.Pattern B Implement a one-to-many relationship as a (non-reversible) third composite term set In this example, to be more realistic, we're using a base geopolitical locations term set that already has some hierachy of its own. Don't let that confuse you. Each term still corresponds to a single
entity in the real world such as India or United Kingdom.In the case of one-to-many relationships, a third term set will also usually be introduced which corresponds to the associative entity. This starts out the same as for one-to-one relationships. In contrast, however, the top level terms here are always derived from the entity at the singular end and the bottom level terms from the multiple end of the relationship.
One geopolitical location (such as India ) has many sites (Calcutta Operations, Calcutta Sales Office).Pattern C
Avoid implementing a many-to-many relationship as a composite term setIt is tempting to combine the elements of a many-to-many relationship into a composite term set, but doing so is usually a mistake. The term set story for many-to-many relationships is not great. SharePoint term sets are simple hierarchies and each term set can consume a term only once. In the above, I was therefore forced to create the last term as a duplicate of
Global Sales Office and
thus begins the slippery slope of losing single identity. We'd now end up with Global Sales Office documents tagged with different IDs across the landscape and so lose our ability to reliably locate all documents that pertain to that office.So what to do? In my opinion MN should resolve to separate term sets and fields in most cases. Instead of trying to combine the
Business Units and
Sites term sets into one I would keep them apart and present them as separate fields.
There is a down side to doing so. The information worker could now pick the business unit
Cosmetics and the site Calcutta Operations, which is an invalid combination. In pre-termstore days, many folk dealt with this situation with custom cascading dropdowns. In the termstore world, we've resorted to dealing with it by constraining the terms available beneath a parent term. Unfortunately, re-use does not play well with that approach in the many-to-many case, as explained above.
So which is the lesser of two evils?
Forfeit the single identity principle
Allow invalid data combinations to be selectedIt may depend on the drivers in your environment but thus far I have always insisted that we uphold single identity. In my experience, losing that has far-reaching, negative impacts not just on current objectives but on our ability to improve information architecture over time.ConclusionStarting with a domain model helps to avoid pitfalls when designing data structures. This holds true for SharePoint term sets. In particular, beware of many-to-many relationships. They do not translate well into combined term sets.Post by: Martin Dreyer
Posted on: 8/22/2015 6:44:00 PM
Description: SharePoint list views that include projected fields can be provisioned via CSOM.
In the SharePoint web interface, projected fields for a lookup field can be specified on the field settings page.
The extra fields from the lookup list can then be consumed in views.
The following CSOM code can be employed to provision such views remotely. In this example I have a list named
Registration which has a lookup field pointing to a list named
Calendar. The internal name of the lookup field is
calendarLookupField.The objective is to add two projected fields as illustrated above. using (var ctx = new ClientContext(url))
ctx.Load(ctx.Web, w => w.Id);
var list = ctx.Web.Lists.GetByTitle("Registration");
var view = list.DefaultView;
"<Join Type='LEFT' ListAlias='cal'>" +
"<FieldRef Name='calendarLookupFld' RefType='Id' />" +
"<FieldRef List='cal' Name='ID' />" +
view.ViewProjectedFields = String.Format(
"<Field Name='eventId' Type='Lookup' List='cal' ShowField='ID' WebId='0'/>" +
"<Field Name='start' Type='Lookup' List='cal' ShowField='EventDate' WebId='0'/>",
These names in the code are aliases, which I chose arbitrarily. Avoid using spaces, etc. when naming them.
cal refers to the Calendar list
eventId refers to the Id field of the Calendar list.
start refers to the EventDate field of the Calendar list.Some learning I went throughThe documentation makes no reference to a
WebId attribute on the projected field definition, but omitting it leads to a runtime error on the view "Unable to cast object of type 'System.Xml.XmlElement' to type 'System.String'". Thanks to Sergei Snitco for providing that insight
here.It may seem weird at first that nothing in the code refers explicitly to the list that we're getting the projected fields from (Calendar in this case) . As per the MSDN reference at the end, this is because the lookup field holds that relationship implicitly.I intially started down the path of omitting the join expression from my code and relying on an implicit join. Then I noticed this advice on MSDN "We do not recommend working without a Joins element. You will maximize your solution’s chances of being compatible with future releases of Microsoft SharePoint Foundation by always using an explicit Join element."ReferencesList Joins and Projections
https//msdn.microsoft.com/en-us/library/office/ee539975(v=office.14).aspxSP 2010 List Joins & SPQuery enchancements. Tobias Zimmergren