London Dev Meetup Rescheduled! Due to unavoidable reasons, the event has been moved to 21st May. Speakers remain the same—any changes will be communicated. Seats are limited—register here to secure your spot!

Complex Find sorting

Vote:
0

I have some difficulties in doing the sorting in Find.

I have the following structure:

class TimeBlock
{
DateTime StartDate
}

class Event
{
ContentArea Times
}

The goal is to sort events by closest future (more than DateTime.Now + x hours) StartDate of their TimeBlocks.

I tried to index all StartDates like this:

[Ignore]
        public virtual DateTime[] StartDates
        {
            get
            {
                var dates = Times?.FilteredItems
                  ?.Select(x => x.GetContent())
                  .Where(b => b != null)
                  .OfType()
                  .DefaultIfEmpty(new CourseInfoBlock { StartDate = DateTime.MinValue })
                  .Select(x => x.StartDate).ToArray()
                  ?? new[] { DateTime.MinValue };
                return dates;
            }
        }



and then do the ordering

Find.Search().Filter.....
.OrderBy(p => p.StartDates, p => p, p => p.GreaterThan(hideBeforeDate), SortMissing.Last, SortOrder.Ascending, SortMode.Min



but I get an exception “No mapping found for [StartDates.$$date] in order to sort on”

I'll be grateful for any help.

#171747
Nov 17, 2016 10:25
Vote:
0

You will need a client convention right?

//using EPiServer.Find.ClientConventions;
 
client.Conventions.ForInstancesOf<Event>()
    .IncludeField(x => x.StartDates);
#171748
Edited, Nov 17, 2016 10:44
Vote:
0

Can you check the index and verify that StartDate is part of the index? (ref the Ignore attribute on your property).

#171750
Nov 17, 2016 10:59
Vote:
0

Yes, I have StartDates of my events indexed

"StartDates": [
        "2016-12-10T03:00:00Z",
        "2016-11-11T11:00:00Z",
        "2016-11-15T17:00:00Z"
    ],
#171751
Nov 17, 2016 11:44
Vote:
0

Maybe new extension with GetClosestStartDate() on event class that returns a single start date and index that instead?

#171753
Nov 17, 2016 12:20
Vote:
0

Hi Daniel,

I cannot do that because ClosestDate on the time of indexing may be different than the closest date on the time of querying.

#171755
Nov 17, 2016 12:54
Vote:
0

My final solution is:

1. Add NestedConvention in initialization module:

SearchClient.Instance.Conventions.NestedConventions.ForInstancesOf<Event>().Add(t => t.StartDatesForIndexing);

2. Create custom class because you signature for Add method is

Expression<Func<TSource, IEnumerable<TListItem>>> expr) where TListItem : class;

my custom class:

 [JsonObject]
    public class DateIndexCustom
    {
        [JsonProperty]
        public DateTime StartDateForIndexing { get; set; }
    }

and property in Event class:

 [Ignore]
        public virtual DateIndexCustom[] StartDatesForIndexing
        {
            get
            {
                var dates = Times?.FilteredItems
                  ?.Select(x => x.GetContent())
                  .Where(b => b != null)
                  .OfType<EventInfoBaseBlock>()
                  .DefaultIfEmpty(new CourseInfoBlock { StartDate = DateTime.MinValue })
                  .Select(x => new DateIndexCustom { StartDateForIndexing = x.StartDate }).ToArray()
                  ?? new[] { new DateIndexCustom { StartDateForIndexing = DateTime.MinValue } };
                return dates;
            }
        }

3. query looks similar to my initial one:

query = query.OrderBy(d => d.StartDatesForIndexing, st => st.StartDateForIndexing, st => st.StartDateForIndexing.GreaterThan(hideBefore));

4. I reindexed all content

#172356
Edited, Dec 01, 2016 9:35
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.