1
votes

I have the following method to return search results based on a supplied query

private List<Item> GetResults(QueryBase qBase)
{
    using (IndexSearchContext sc = SearchManager.GetIndex("story").CreateSearchContext())
    {
        var hits = sc.Search(qBase, int.MaxValue);

        var h1 = hits.FetchResults(0, 25);
        var h2 = h1.Select(r => r.GetObject<Item>());
        var h3 = h2.Where(item => item != null);
        return h3.ToList();
    }
}

The index being searched indexes web and master content. If I pass in a query that I know matches a single published item and break at the line beginning var h2 = then I see the variable hits has 2 items. This I expect because actually the items are both the same item, one from web and one from master.

However, the variable h1 only has a single result. The result from web has been omitted.

This is the case whether I'm debugging in the context of web or master. Can anyone explain?

1

1 Answers

1
votes

When fetching the items using FetchResults method, Sitecore groups the items from lucene by the id of the item. First of the items becomes a SearchResult in the resulting SearchResultCollection object, and other items become Subresults for this results.

For example if you have a home item with id {110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9} with one published version and 4 versions in different languages for the home item, what you'll get from lucene is a single result and 4 subresults for this result:

using (IndexSearchContext sc = SearchManager.GetIndex("story").CreateSearchContext())
{
    var hits = sc.Search(qBase, int.MaxValue);

    var h1 = hits.FetchResults(0, 25);
    foreach (SearchResult result in h1)
    {
        var url = result.Url;

        foreach (SearchResult subresult in result.Subresults)
        {
            var subUrl = subresult.Url; // other versions of this item
        }
    }
}

The urls for results and subresults in my case would be:

sitecore://web/{110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9}?lang=en&ver=1
sitecore://master/{110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9}?lang=en&ver=1 (subresult)
sitecore://master/{110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9}?lang=ja-JP&ver=1 (subresult)
sitecore://master/{110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9}?lang=de-DE&ver=1 (subresult)
sitecore://master/{110D559F-DEA5-42EA-9C1C-8A5DF7E70EF9}?lang=da&ver=1 (subresult)

so for retrieving the all the items with their versions you can use this code:

private List<Item> GetResults(QueryBase qBase)
{
    using (IndexSearchContext sc = SearchManager.GetIndex("story").CreateSearchContext())
    {
        var hits = sc.Search(qBase, int.MaxValue);

        var h1 = hits.FetchResults(0, 25);
        var h2 = h1.Select(r => r.GetObject<Item>()).ToList();

        // add other versions of item to the resulting list
        foreach (IEnumerable<SearchResult> subresults in h1.Select(sr => sr.Subresults))
        {
            h2.AddRange(subresults.Select(r => r.GetObject<Item>()));
        }

        var h3 = h2.Where(item => item != null);
        return h3.ToList();
    }
}

You can not assume with item will be returned as the first one from the lucene and which items will be returned as subresults. If you want to get any specific item you need to pass version number, language and database to the query.