4

I'm trying to implement a tagging functionality that allows the content editor to add tags for a specific component and the c# to search for items containing a given set of tags

Let's say our Sitecore Lucene index looks like this

x = ["csharp", "dotNet", "java", "vbnet", "c"]
y = ["csharp", "computers", "dotNet"]
z = ["java"]

I want to perform a search query like this

["csharp", "dotNet"]

and have it return x and y, but y will be scored/ranked higher than x because it has more matches than any other items in the index...

I'm familiar with Elastic Search(which is built on Lucene) and I know the way to do this is

{
  "terms" : {
      "tags" : [ "csharp", "dotNet" ]
  }
}

but unsure as the same can be achieved using the ContentSearchAPI in Sitecore Lucene.

My current code is

        var tags = GetTagsFromSomewhere();

        using (var context = SearchIndexResolver.GetIndex(ContextItem).CreateSearchContext())
        {
            var queryable = context.GetQueryable<CustomType>();

            foreach (var tag in tags)
            {
                queryable = queryable
                    .Where(i => i.Tags.Contains(tag));

                var results = queryable.GetResults();
            }
        }

Thanks

1 Answer 1

4

It's possible to implement. Try something like below:

var tags = GetTagsFromSomewhere();

            using (var context = SearchIndexResolver.GetIndex(ContextItem).CreateSearchContext())
            {
                var queryable = context.GetQueryable<CustomType>();

                var predicat = PredicateBuilder.False<BaseIndexModel>();

                foreach (var tag in tags)
                {
                    predicat = predicat.Or(q => q.Tags.Contains(tag).Boost(1.5f));
                }

                queryable = queryable.Where(predicat);

                var results = queryable.GetResults();
            }

It works for me locally (similar code).

I've a bit updated your code with added a boosting for a condition. In general the boosting allows us to increase a wight of coditions (or Items, Fields. Read more about Search result boosting).

Also I've used a PredicateBuilder, which allows us to build queries more flexible. You can read, for example, the following article about using PredicateBuilder: Building Dynamic Content Search LINQ Queries In Sitecore by Dan Cruickshank

7
  • Hi, thanks for the response. Your query worked well, however, for some odd reason the results are ranked. I went into debugging mode and each returned result has a score of 0. I find that pretty odd too, I'm sure that has something to do with why it's not being ranked correctly. Do you know any reason why? My code is exactly the same as you wrote it. Nov 16, 2017 at 10:41
  • It probably known issue. Try to see the following post: stackoverflow.com/questions/31385013/… Nov 16, 2017 at 11:35
  • And why do you need the score value in general? Do you want to apply an extra sorting? Nov 16, 2017 at 11:36
  • I don't need the score value, my problem is that, the results are not ranked in order of which item contains the best "match". I have been trying to figure out why and since the score is at 0, I assume that might play a part in why the results are ordered properly. I viewed the Lucene logs and saw that the boosting still isn't applied on the query. I've looked at that stackoverflow post and it doesn't seem to work. The standard values button says "The current item does not contain any fields.", even though it contains 3 fields haha. Nov 16, 2017 at 11:59
  • Thanks for the help, if all fails, I could just retrieve all Items that contain tagIds and then I could write some code to sort it manually. It's just that I wanted to take advantage of Lucene's searching features as I know they're well optimized for speed. Nov 16, 2017 at 12:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.