I'm trying to figure out why certain code is needed in order for a content search query to work with Azure search. I have a multilist field which is indexed by the default indexer in Sitecore, meaning the index field contains data such as
"search_tags": "{6537B24A-1B80-4EA0-BBA2-3D3923E0ED4F}|{FA5E4033-F48E-4749-A76A-B62C422D4ABA}|{9B61C09C-2029-4AD6-859E-477F2C1AB95B}"
I have my own class called IndexedItem
inheriting Sitecore.ContentSearch.SearchTypes.SearchResultItem
. It has a field property as follows:
[IndexField("tags")]
public List<string> Tags { get; set; }
Using a query against the Tags property does not work (the clause is not included in the request to azure search).
private Expression<Func<IndexedItem, bool>> GetPredicatesForTags(
IEnumerable<string> tagIds)
{
var tagsPredicate = PredicateBuilder.False<IndexedItem>();
foreach (var tagId in tagIds)
{
tagsPredicate = tagsPredicate.And(item => item.Tags.Contains(tagId));
}
return tagsPredicate;
}
Using string.Contains
against the field shown below also does not work:
private Expression<Func<IndexedItem, bool>> GetPredicatesForTags(
IEnumerable<string> tagIds)
{
var tagsPredicate = PredicateBuilder.False<IndexedItem>();
foreach (var tagId in tagIds)
{
tagsPredicate = tagsPredicate.And(item => item["tags"].Contains(tagId));
}
return tagsPredicate;
}
If I add an extra Or
predicate with an equals clause, it works:
private Expression<Func<IndexedItem, bool>> GetPredicatesForTags(
IEnumerable<string> tagIds)
{
var tagsPredicate = PredicateBuilder.False<IndexedItem>();
foreach (var tagId in tagIds)
{
tagsPredicate = tagsPredicate.And(item => item["tags"].Contains(tagId));
tagsPredicate = tagsPredicate.Or(item => item["tags"] == tagId);
}
return tagsPredicate;
}
Is this a quirk of Azure Search, or is it common to ContentSearch in general?
This question: Multilist fields and Azure Search describes a similar problem, but the OP is using a simple string type property on their SearchResultItem class, so the scenario is slightly different.