How to control the priority of subqueries in Sitecore ContentSearch using Solr Provider?

Version Information: I am working with Sitecore 7.5 build 141003, using Solr v4.7 as the search engine / index server. I also use the standard Sitecore Solr provider without custom indexes.

Target: I am using Sitecore ContentSearch LINQ with PredicateBuilder to compile some flexible and nested queries. Currently, I need to search in a specific “Root item”, excluding templates with a “folder” in their name, also excluding items with “/ testing” in their path. At some point, a “root element” may have more than one element, and therefore the path may contain (currently just “testing”). In these cases, the idea is to use a PredicateBuilder to construct an external AND predicate with an internal, OR for multiple exceptions to the root element and paths.

Problem: At the moment, I am dealing with the issue of nesting order and priorities for these predicates / conditions. I tested several approaches and combinations, but the problem that I continue to work with is TemplateName.Contains and Item ["_ fullpath"]. Contains priority over Paths.Contains, which ends with 0 results each time.

I use Search.log to check the query output, and I manually checked against the Solr administrator by running queries against it to compare the results. Below you will find examples of combinations that I tried using Sitecore Linq and the queries that they create for Solr.

Source code example:

The original test with a list for root elements

// sometimes will be 1, sometimes will be multiple
var rootItems = new List<ID> { pathID };  // simplified to 1 item for now
var query = context.GetQueryable<SearchResultItem>();
var folderFilter = PredicateBuilder.True<SearchResultItem>().And(i => !i.TemplateName.Contains("folder") && !i["_fullpath"].Contains("/testing"));
var pathFilter = PredicateBuilder.False<SearchResultItem>();
pathFilter = rootItems.Aggregate(pathFilter, (current, id) => current.Or(i => i.Paths.Contains(id)));
folderFilter = folderFilter.And(pathFilter);
query.Filter(folderFilter).GetResults();

: (-_templatename: (* folder *) AND -_fullpath: (*/testing *)) AND _path: (730c169987a44ca7a9ce294ad7151f13)

, " ", . Solr, 0 . , , "" , .

PredicateBuilder, . ( "query.Filter(pred1).Filter(pred2)" ) , .

:

Alt. 1 - "Paths.Contains"

var query = context.GetQueryable<SearchResultItem>();
var folderFilter = PredicateBuilder.True<SearchResultItem>().And(i => !i.TemplateName.Contains("folder") && !i["_fullpath"].Contains("/testing"));
folderFilter = folderFilter.And(i => i.Paths.Contains(pathID));
query.Filter(folderFilter).GetResults();

: (-_templatename: (* folder *) AND -_fullpath: (*/testing *)) AND _path: (730c169987a44ca7a9ce294ad7151f13)

Alt 2. ,

var query = context.GetQueryable<SearchResultItem>();
var folderFilter = PredicateBuilder.True<SearchResultItem>().And(i => !i.TemplateName.Contains("folder") && !i["_fullpath"].Contains("/testing"));
var pathFilter = PredicateBuilder.False<SearchResultItem>().Or(i => i.Paths.Contains(pathID));
folderFilter = folderFilter.And(pathFilter);
query.Filter(folderFilter).GetResults();

: (-_templatename: (* folder *) AND -_fullpath: (*/testing *)) AND _path: (730c169987a44ca7a9ce294ad7151f13)

Alt 3 - "" , "" "",

var query = context.GetQueryable<SearchResultItem>();
var folderFilter = PredicateBuilder.True<SearchResultItem>().And(i => !i.TemplateName.Contains("folder") && !i["_fullpath"].Contains("/testing"));
var pathFilter = PredicateBuilder.False<SearchResultItem>().Or(i => i.Paths.Contains(pathID));
var finalPredicate = PredicateBuilder.True<SearchResultItem>().And(folderFilter).And(pathFilter);
query.Filter(finalPredicate).GetResults();

: (-_templatename: (* folder *) AND -_fullpath: (*/testing *)) AND _path: (730c169987a44ca7a9ce294ad7151f13)

: , , , - / , , "" - . , , " " , - :

(-_ templatename: (* folder *) AND -_fullpath: (*/testing *) AND (_path: (730c169987a44ca7a9ce294ad7151f13) _path: (12c1aa7f60fa4e8d9f0a983bbbb40d8b))) ​​

(-_ templatename: (* folder *) AND -_fullpath: (*/testing *) AND (_path: (730c169987a44ca7a9ce294ad7151f13)))

, Solr. Sitecore ContentSearch Linq .

- , ? Sitecore Linq, IQueryable "GetFacets" "GetResults".

Update: , , SO, , . , () , :

var folderFilter = PredicateBuilder.True<SearchResultItem>().And(i => !i.TemplateName.Contains("folder")).And(i => !i["_fullpath"].Contains("/testing"));
var rootItems = new List<ID> { pathID, path2 };
// or paths separately
var pathFilter = PredicateBuilder.False<SearchResultItem>();
pathFilter = rootItems.Aggregate(pathFilter, (current, id) => current.Or(i => i.Paths.Contains(id)));   
var finalPredicate = folderFilter.And(pathFilter);
var query = context.GetQueryable<SearchResultItem>();
query.Filter(finalPredicate).GetResults();

: ((-_templatename: (* folder *) AND -_fullpath: (*/testing *)) AND (_path: (730c169987a44ca7a9ce294ad7151f13) _path: (12c1aa7f60fa4e8d9f0a983bbbb40d8b))) ​​

"_templatename" "_fullpath", .

.

+4
3

, Sitecore, .

Solr (http://wiki.apache.org/solr/FAQ), "" " foo AND -baz ', ' foo AND (-bar) 'does not? , 0.

"" (.. ), . Solr , BooleanQuery, , docs (::)

BoolenQuery - BooleanQuery, , , ( ) - - , , .

, Sitecore Solr, , 0 , , Solr doc. , , , " " (*: *) .

, , , , , DLL , , .

398622 .

:

((-_templatename:(*folder*) AND -_fullpath:(*/testing*) AND *:*) AND _path:(730c169987a44ca7a9ce294ad7151f13))

, :

((-_templatename:(*folder*) AND -_fullpath:(*/testing*) AND *:*) AND (_path:(730c169987a44ca7a9ce294ad7151f13) OR _path:(12c1aa7f60fa4e8d9f0a983bbbb40d8b)))

, . - , Sitecore , . , Solr.Index Solr.Indexes.Analytics.

+2

2 , AND , , 2 , , :

// the path part of the query. OR together all the locations
var pathFilter = PredicateBuilder.False<SearchResultItem>();
pathFilter = pathFilter.Or(i => i.Paths.Contains(pathID));
pathFilter = pathFilter.Or(i => i.Paths.Contains(pathID2));
...

// the exclusions, build them up seprately
var query = PredicateBuilder.True<SearchResultItem>();
query = query.And(i => !i.TemplateName.Contains("folder"));
query = query.And(i => !i["_fullpath"].Contains("/testing"));

// join both parts together
query = query.And(pathFilter);

():

!templateName.Contains("folder") 
AND !_fullpath.Contains("/testing") 
AND (path.Contains(pathID1) || path.Contains(pathID2))

, fisrt, ExcludeTemplate Sitecore.ContentSearch.Solr.DefaultIndexConfiguration.config. , :

<exclude hint="list:ExcludeTemplate">
  <MyTemplateId>{11111111-1111-1111-1111-111111111111}</MyTemplateId>
  <MyTemplateId>{22222222-2222-2222-2222-222222222222}</MyTemplateId>
</exclude>
0

I tried the following code and it really generated your required output request. The trick was to use PredicateBuilder.True () when creating a Path filter request, not sure if this is normal behavior from the Content Search API or its error

var query = context.GetQueryable<Sitecore.ContentSearch.SearchTypes.SearchResultItem>();
var folderFilter = PredicateBuilder.True<SearchResultItem>().And(i => !i.TemplateName.Contains("folder") && !i["_fullpath"].Contains("/testing"));
var pathFilter = PredicateBuilder.True<SearchResultItem>();
pathFilter = pathFilter.Or(i => i.Paths.Contains(Path1) || i.Paths.Contains(Path2));

folderFilter = folderFilter.And(pathFilter);
0
source

Source: https://habr.com/ru/post/1598248/


All Articles