posting the content from the above link:
https://mikesnotebook.wordpress.com/2014/06/03/working-with-the-sharepoint-
search-rest-api-on-anonymous-sites/
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.
function doSearch() {
//this has trimduplicates=false to support logged in users,
//while the file that is referenced has been 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();
}