Working with the SharePoint Search REST API on Anonymous Sites

I’m building a little SharePoint site that will be available anonymously (I’ve done quite a bit of work on anonymous sites in 2010, but this is a bit new for me in SharePoint 2013). So, a while back I went through the process of configuring the queryparametertemplate.xml file to enable the Search REST API to be available anonymously. I discovered I needed to do this by getting an error message. That was my bad, as I hadn’t scrolled all the way to the bottom of the doc to see that it clearly said “You can configure search to support Search REST queries from anonymous users”. (I like the optimist “you can“, not the more correct “you must“.)

But after that, it seemed to work fine and everything went smoothly. That is, until I realized it wasn’t returning all results. It’s important to know that I’m returning rows from a single list, and many rows are similar to others but just differing by dates or one other field. So, why was it returning, for example, one row when it should have returned three? Because the search api has trim duplicates on by default. This is normally a great default. But with anonymous sites, the normal APIs for interacting with lists are not available, and so to do things like return items from a single list requires the use of search. Trimming dups for this use case is not good. But, no worries, I just added &trimduplicates=false to the REST call, and it worked fine. Almost.

Modifying the URL worked for logged in users, but not anonymous users. When testing as an anonymous user, it simply ignored the trimduplicates parameter. In hindsight, it’s really pretty obvious. All settings are controlled by the xml file mentioned above. And so, I modified the XML file to have “false”, and … it didn’t work. I don’t know why it didn’t work. It seems like it really should have worked. But it didn’t. While I was glaring at the screen, I noticed another setting named “TrimDuplicatesKeepCount” which had a value of one.

So, I did a quick search for this property, and found the documentation which helpfully states: “Use TrimDuplicatesKeepCount to specify the number of documents to retain when TrimDuplicates is true.”

I had set trimduplicates to false, so this property shouldn’t do anything. But it was behaving as if it was true. So, I set it to 100. And it works. The search api is now returning all items that it should, for both logged in and anonymous users. Of course, this complicates testing, as the functionality of every component that uses this interface could be different for different users.

But, I now know how to return items from a list for an anonymous site. I think.

function doSearch() {
 //this has trimduplicates=false to support logged in users, 
 //while the file that is referenced has been modified to support anonymous users
     var requestUri = "/_api/search/query?querytext='" + searchstring + 
         " contenttype=\"Event\"&selectproperties='Title,StartDateOWSDate,EndDateOWSDate'&trimduplicates=false&QueryTemplatePropertiesUrl='spfile://webroot/queryparametertemplate.xml'&sortlist='StartDateOWSDate:ascending'";
      $.ajax({
                url: requestUri,
                type: "GET",
                async:true,
                headers: { "ACCEPT": "application/json;odata=verbose" },
                success: function (data) {
                    onDoSearchSucceeded(data);
                },
                error: function (d) {
                   // alert("That didn't work");
                }
            });    
}

function onDoSearchSucceeded(data) {
  var results = data.d.query.PrimaryQueryResult.RelevantResults.Table.Rows.results;
  $.each(results, function (index, result) {
     var resultsRow = result.Cells.results;
     var startDate = getShortDate(getResultValueByKey('StartDateOWSDate',resultsRow));
     ...
  });
}

function getResultValueByKey(fieldName, arr){
    var v='';
    $.each(arr, function (index, item) {
        if(item.Key == fieldName){
            v= item.Value;
            return(false);
        }
    });
    return v;
}

function getShortDate(d){
    // padding function
    
    var d2 = new Date(d);
    var s = function(a,b){return(1e15+a+"").slice(-b)};

    // default date parameter
    if (typeof d2 === 'undefined' || d2==''){
        d2 = new Date();
    };

    // return ISO datetime
    return  s(d2.getMonth()+1,2) + '-' + s(d2.getDate(),2) + '-' + d2.getFullYear();   
}












 

 

 

 

Advertisements

2 thoughts on “Working with the SharePoint Search REST API on Anonymous Sites

  1. Pieter Temmerman

    Did you happen to find the cause of why SharePoint was ignoring the trimmedduplicates set to false property? Any input is appreciated.

    Reply
    1. Mike G Post author

      I do not. The trick I outlined in the post works for me, but I have never learned why it didn’t work the way it was supposed to.

      Reply

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s