1
votes

I have a IQueryable<T> object as search results object. I apply the filtering and sorting on this search object.

Before I call the GetResults(), I want to order the results based on one of the field's (Fieldname - Priority) value. So for all the items in the IQueryable<T> object, I want to order them desc by Priority field, so all the items which has a value for that field stay at the top and the rest are at the bottom.

I have the fieldmap entry for Priority field.

search.OrderByDescending(i => !string.IsNullOrEmpty(i.GetItem().GetFieldValue("Priority")))

The above command doesn't work. Apparently, I can't use Sitecore extension methods with IQueryable?

If I convert search.ToList(). Do the ordering and then convert it back to AsQueryable(), I get the following error:

There is no method 'GetResults' on type 'Sitecore.ContentSearch.Linq.QueryableExtensions' 
that matches the specified arguments

Is there a neat and quick way to get around this?

Cheers

2
I apply the filtering and sorting on this search object - Are you sorting by multiple fields? e.g. Title and Priority?jammykam
@jammykam - sort of yes. I sort them first on the criteria chosen by the user - like Name, Date created etc. Once I get the results back, I need to order them by priority field.NomadTraveler
Are you paging results or can you order after get results?Chris Auer
I am paging results @dnstommyNomadTraveler
Ahh ok. Did the result below work? I know that Lucene treats everything as strings. Working with int's is a pain.Chris Auer

2 Answers

0
votes

I think you just need to add your field to your SearchResultItem and mark it as an int. I am making the assumption that the field is an int. Make a custom class that inherits SearchResultItem.

public class CustomSearchResultItem : SearchResultItem
{
    [IndexField("Priority")]
    public int Priority { get; set; }
}

Then use it in your search. Finally order by it.

using (var context = ContentSearchManager.GetIndex("sitecore_master_index").CreateSearchContext())
{
    var results = context.GetQueryable<CustomSearchResultItem>().Where(prod => prod.Content.Contains("search box text").OrderByDescending(t => t.Priority);
}

Some data found here.

http://www.sitecore.net/learn/blogs/technical-blogs/sitecore-7-development-team/posts/2013/10/sorting-and-ordering-results.aspx

0
votes

You can order search results using multiple fields by using the OrderByDescending combined with ThenByDescending. So you would need to order by Priority and then by [Name|Date|Whatever].

I want to order them desc by Priority field, so all the items which has a value for that field stay at the top and the rest are at the bottom.

I sort them first on the criteria chosen by the user - like Name, Date created etc. Once I get the results back, I need to order them by priority field

You are conflicting yourself in the questions and comments. If you want the results with priority first and then by user selected results then the following will work:

query = dataQuery.OrderByDescending(i => i.Title).ThenByDescending(i => i["Priority"]);
var results = query.GetResults().Hits.Select(h => h.Document);

There was a bug in earlier version of Sitecore which meant that the ThenBy clause will be added before the OrderBy clause hence it is added in reverse above. You may want to check if this is fixed in the current version. If so simply change your query to:

query = dataQuery.OrderByDescending(i => i["Priority"]).ThenByDescending(i => i.Title);

You don't have to add the field to your SearchResultItem if you just want to order by it, only if you need the actual value of that field returned to as well.

If you need to order by a custom user supplied value then you can pass in i => i["whatever-field-the-user-has-selected"] instead of i.Title.

You can find more info in this blog post.