5

I'm trying to create an alert on a list. The alert should only trigger on a subset of the list items for which a certain managed metadata field has a certain value. So I'm setting the Filter-Property of the AlertCreationInformation to a CAML-query. There is no problem getting the filter to work for say filtering on a choice field using

ClientContext = GetMy365Context(...);
Web web = ctx.Web;
List list = web.Lists.GetByTitle("NotifyTest");
User user = ctx.Web.SiteUsers.GetByEmail("someone@example.com");
ctx.Load(web);
ctx.Load(list);
ctx.Load(user);
ctx.ExecuteQuery();

AlertCreationInformation aci = new AlertCreationInformation()
{
    AlertFrequency = AlertFrequency.Immediate,
    AlertType = AlertType.List,
    AlwaysNotify = true,
    EventType = AlertEventType.All,
    DeliveryChannels = AlertDeliveryChannel.Email,
    Title = "Alert filtered on choice",
    User = user,
    AlertTemplateName = "SPAlertTemplateType.GenericList"

};
aci.List = list;
aci.Filter = "<Query><Eq><FieldRef Name=\"MyChoiceField\" /><Value Type=\"Text\">MyChoiceValue</Value></Eq></Query>";

web.Alerts.Add(aci);
ctx.ExecuteQuery();

But, I was unable to find any proper documentation on the supported CAML for Filter. E.g. <In> is not supported as well as Type="Choice"

So my question is, what query can I use to filter on a multivalue managed metadata field? So far I have tried using the GUID of the term, the lookup id of the term in the taxonomy hidden list, the text-value of the term, the <contains>-operator, the <eq>-operator but without any luck.

2
+200

The problem you are running into is that Alert.filter accepts a very limited subset of CAML and what that subset allows is anybody's guess (i.e. completely undocumented, of course you already know that by now).

A while back I read an answer on a forum to a similar question that provide a novel approach to figure out what worked. I would reference it here, but I can't seem to find it now. Anyway, the approach was:

  1. Create a view that filters the way you want the alert to filter.
  2. Setup an alert on that view.
  3. Programmatically, look at that alert and look at the filter.

The reason this works is because the alert isn't actually tied to the view, it copies the filter. So if the view changes, the alert will be out of sync with it.

So I setup a quick test with a multi-select metadata site column, creatively named ManagedMetadata, containing some fruits and vegetables, created a list that used the field, and a view that only showed items with Broccoli as a value. Finally, I created an alert on that view. Then I created some items with and without Broccoli and checked that the alert works, which it does.

Now, I launch the debug console and run this code:

var ctx = SP.ClientContext.get_current();
var web = ctx.get_web();
var alerts = web.get_alerts();

ctx.load(web);
ctx.load(alerts);

ctx.executeQueryAsync(
    function() {
        var en = alerts.getEnumerator();
        while (en.moveNext()) {
            console.log(en.get_current());
        }
    },
    function(sender, args) {
        console.log(args.get_message());
    }
);

When I run that code, this what gets dumped for that alert:

enter image description here

The actual filter is:

<Query><Eq><FieldRef Name=\"ManagedMetadata\"/><Value type=\"string\">brocoli</Value></Eq></Query>

The only difference I see is that the value type is set to string instead of text like you have. Why? I cannot say, but it seems to work.

Note that I'm doing this in SharePoint online. If you mentioned what version of SharePoint you're on, I missed it. Anyway, hope this helps.

  • If anybody finds the original question/answer I mention, let me know, I owe that guy a beer. Also note that I spelled broccoli wrong in my original taxonomy and just didn't bother to fix it, thus it's wrong on purpose in the filter ;) – Joe McShea Apr 12 at 17:41
  • I tried this before but messed up something when creating the alert based on the view :-/ Now after trying it again and with the knowledge that it has to work this way I got it working. One interesting point is that the test whether a multi value taxonomy field contains some value results in an <Eq>-operator... and it worked. freaks me out :-) – ben Apr 12 at 18:51
  • 1
    <Eq> actually works in general with CAML and multi-valued fields. It would really suck for mulit-valued fields if it didn't. – Joe McShea Apr 12 at 18:53
1

There are 2 methods to query a list/library that contains a managed metadata column:

Query against Term Name

Query Against WSSID

Method 1 (will look something similar to this):

alert.Filter = @"<Query>
              <Contains>
                  <FieldRef Name='" + MyTaxonomyFieldName + @"' />
                  <Value Type='Text'>" + tagName + @"</Value>
              </Contains>
            </Query>";

Method 2:

alert.Filter = @"<Query>
              <In>
               <FieldRef LookupId='TRUE' Name='" + MyTaxonomyField + @"' />
                <Values>
                   <Value Type='Integer'>" + tagLookupID + @"</Value>
                </Values>
              </In>
             </Query>";

it is recommended to use the second method to avoid situations where the term name is used under different term groups!

  • I got it working using method 1. When trying method 2 the server responded that the query contained an unknown operator. Must be <in>. – ben Apr 12 at 18:53
  • I fixed your code to work properly with alerts. – ben Apr 12 at 18:55
  • I'm sorry I had to award the bounty to Joe's answer although yours also helped in the process of soling it, but i had to act according to meta.stackexchange.com/questions/2786/… – ben Apr 12 at 19:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.