Gravatar for ssartell@rightpoint.com

Question by ssartell, Aug 5, 2015 11:26 PM

Coveo for Sitecore Rest API returning results from wrong index

I've read multiple forum posts that say Coveo for Sitecore should automatically determine which index it should retrieve results from. However, I seem to get results from both the master and web indexes. Obviously I do not want show results from the master index, and it seems like a security risk to filter out the master results via JavaScript. How do I fix this?

Also, here are the forum posts I was referring to: https://answers.coveo.com/questions/3777/multi-site-sitecore-and-multiple-indexes https://answers.coveo.com/questions/3412/query-custom-index

Gravatar for jflheureux@coveo.com

Comment by Jean-François L'Heureux, Aug 6, 2015 8:49 AM

When executing the query in the JS UI, open the developer tools and inspect the network request. Can you add the "q", "aq" and "cq" form parameters values please to see what is the query you are executing?

Thanks

Jeff

Gravatar for ssartell@rightpoint.com

Comment by ssartell, Aug 6, 2015 9:07 AM

Right now none of those parameters are set. If I add a data-hidden-expression to the SearchInterface, I see that filter come through the aq parameter.

2 Replies
Gravatar for jgiordano@coveo.com

Answer by jgiordano, Aug 7, 2015 10:45 AM

Hi @ssartel, let's say that you have the pipeline default located in the folder ./pipelines/default. In that folder, open the main.js and add the following:

Coveo.onPreprocessQuery(function(query) {
  // Make sure the constant expression is not null.
  query.constantExpression = query.constantExpression || "";

  var filter = "@syssource=\"Name of your Sitecore source\"";
  var append = query.constantExpression.length > 0;

  // "" => "@syssource=\"Name of your Sitecore source\""
  // "foo OR bar" => "(foo OR bar) AND @syssource=\"Name of your Sitecore source\""
  query.constantExpression = append
    ? "(" + query.constantExpression + ") AND " + filter
    : filter;
});

This should get you started. Additional tips & tricks:

  • When you modify the main.js of a pipeline, you don't need to restart the service. The main.js is reloaded on save.
  • Let's say that your endpoint is http://localhost/rest/search. You can test your modifications to main.js with this query: http://localhost/rest/search?debug=1&pipeline=default&q=foo&cq=bar. The debug=1 is useful to know what is going on in the service. One thing you'll want to look at is the field constantExpression of the response. This field hold the value of your modified constant query sent to the index.
Gravatar for ssartell@rightpoint.com

Comment by ssartell, Aug 7, 2015 11:52 AM

That works perfectly! Thank you!

If you don't mind, I have a follow up question that maybe deserves it's own thread, but I feel bad spamming with too many questions. SearchInterface has a hiddenExpression property which gets applied to the advancedExpression. The problem I have is that it impacts the highlighting. I know I can add a custom handler to the buildingQuery event to add a filter to constantExpression which won't show up, but this just feels like a bug to me. Am I wrong? Is there a better approach?

Gravatar for jflheureux@coveo.com

Comment by Jean-François L'Heureux, Aug 7, 2015 2:05 PM

Coveo.SearchProvider.config file has a <rankingIgnoredFields> element to define fields that shouldn't be used for ranking and highlighting. You can add the fields you don't want highlighting for (e.g.: fields you use by default in advanced query expressions) in this list.

After modifying this <rankingIgnoredFields> element, you need to index at least one Sitecore item to synchronize the configuration with CES. Then, the setting should be effective immediately.

Gravatar for jflheureux@coveo.com

Comment by Jean-François L'Heureux, Aug 7, 2015 2:07 PM

And don't feel bad about posting multiple separate questions. It's always better to have one thread per question. Especially when the questions are relevant like yours!

Gravatar for jgiordano@coveo.com

Comment by jgiordano, Aug 7, 2015 2:21 PM

I think the best would be to create a separate question so it can help others having this specific issue. That said, it's not clear what is your desired end result. That said, indeed terms in the advanced expression will be highlighted and not those in the constant expression.

Gravatar for ssartell@rightpoint.com

Comment by ssartell, Aug 8, 2015 9:19 AM

rankingIgnoredFields worked. Thanks!

Gravatar for jflheureux@coveo.com

Answer by Jean-François L'Heureux, Aug 6, 2015 9:39 AM

Since you don't have any "q" (Basic query), "aq" (Advanced query) and "cq" (Constant query) when you search, that explains why you are getting all the CES index documents. It is equivalent of searching for "@sysuri" or "@uri". Since every CES documents have an URI, it returns all the indexed documents.

Do you use the "Coveo Search [View] Resources" and "Coveo Search [View]" sublayouts/renderings installed with Coveo for Sitecore or you implemented your own UI controls with HTML and JS by yourself? Only the installed components will automatically filter the query to get the documents of the site's index.

Gravatar for ssartell@rightpoint.com

Comment by ssartell, Aug 6, 2015 10:17 AM

We implemented our own renderings using the JS Search Framework. Relying on filters implemented via client-side code to hide documents from the master database is not an acceptable solution for me from a security standpoint. I guess I could remove the master index entirely if that's the only way, but I was hoping there was some way to configure the Sitecore rest endpoint to scope to the right index.

Gravatar for jflheureux@coveo.com

Comment by Jean-François L'Heureux, Aug 6, 2015 11:20 AM

In this case, you could leverage the Coveo Search API Query Pipelines. To implement the filtering feature, I would use a Coveo.onPreprocessQuery event handler to append the desired filter (@syssource=="Name of your Sitecore source") to the constant query ((existing constant query) (@syssource query)). You'll need 2 pipelines: one for each Sitecore index/database. In your JavaScript code, you'll need to set the [pipeline][2] property on your query parameters to the name of the desired pipeline based on the Sitecore context database.

Gravatar for ssartell@rightpoint.com

Comment by ssartell, Aug 6, 2015 12:02 PM

Couldn't a malicious user still remove the JS pipeline setting and get access to the master index?

Gravatar for jflheureux@coveo.com

Comment by Jean-François L'Heureux, Aug 6, 2015 1:06 PM

In that case, modify also the default pipeline to add a (NOT @sysuri) filter. That way, a malicious user removing the pipeline name in an HTTP request would get no results.

Gravatar for ssartell@rightpoint.com

Comment by ssartell, Aug 7, 2015 10:13 AM

Do you have an sample pipeline file that applies a filter that I could look at? I tried adding one with a query expression, restarted the API service, but it didn't seem to impact the results. Also, I really appreciate your help. Being relatively new to Coveo can be a bit daunting with all the various points of modification.

Ask a question