如何根据弹性中的时间对包含日期和时间的嵌套对象进行排序

how to sort a nested object that contains date and time based on time in elasic

我有一个名为 store 的索引,它包含一个嵌套对象作为列表 WorkTimes

WorkTimes 列表有打开时间和关闭时间,也许它有多个 OpenTimeCloseTime.

我需要做的是根据开盘时间和收盘时间对这个指数进行排序。 OpenTime 需要大于当前时间,CloseTime 需要小于当前时间。

到目前为止,这是我的实现:

var allfilters = new List<Func<QueryContainerDescriptor<Store>, QueryContainer>>();
            if (storeCategoryIds.Any())
            {
                allfilters.Add(fq => fq.Terms(t => t.Field(f => f.StoreCategoryIds).Terms(storeCategoryIds)));
            }

            if (storeSubCategoryIds.Any())
            {
                allfilters.Add(fq => fq.Terms(t => t.Field(f => f.StoreSubCategoryIds).Terms(storeSubCategoryIds)));
            }

            var stores = await _elasticClient.SearchAsync<Store>(s => s.Index(index).From(from).Size(size)
                    .ScriptFields(sf => sf
                    .ScriptField("distance", descriptor => descriptor
                    .Source("doc[\u0027location\u0027].arcDistance(params.lat,params.lon)")
                    .Lang("painless")
                    .Params(p => p.Add("lat", lat).Add("lon", lng))))
                    .Query(query => query
                    .Bool(b=>b.Filter(allfilters)))
                    .Query(query=>query
                    .Bool(b => b
                    .Filter(filter => filter
                    .GeoDistance(geo => geo
                    .Field(f => f.Location)
                    .Distance(10, DistanceUnit.Kilometers).Location(lat, lng)
                    .DistanceType(GeoDistanceType.Arc)))
                    .Must(m => m
                    .QueryString(qs => qs
                    .Fields(f => f
                    .Fields(f1 => f1.Title))
                    .Query(searchQuery)))))
                    .Sort(sort => sort
                    .GeoDistance(g => g
                    .Field(f => f.Location)
                    .Order(SortOrder.Ascending)
                    .Points(new GeoLocation(lat, lng))
                    .DistanceType(GeoDistanceType.Arc)
                    )).Source(sr => sr.IncludeAll()));

            var storesArray = stores.Documents?.ToArray();
            var arrayCount = 0;
            foreach (var fieldValues in stores.Fields)
            {
                var distance = fieldValues.Value<double>("distance");
                storesArray[arrayCount].Distance = distance;
                arrayCount++;
            }
            return storesArray?.ToList();

你可以这样做

var allfilters = new List<Func<QueryContainerDescriptor<Store>, QueryContainer>>();
            if (storeCategoryIds.Any())
            {
                allfilters.Add(fq => fq.Terms(t => t.Field(f => f.StoreCategoryIds).Terms(storeCategoryIds)));
            }

            if (storeSubCategoryIds.Any())
            {
                allfilters.Add(fq => fq.Terms(t => t.Field(f => f.StoreSubCategoryIds).Terms(storeSubCategoryIds)));
            }

            var stores = await _elasticClient.SearchAsync<Store>(s => s.Index(index).From(from).Size(size)
                    .ScriptFields(sf => sf
                    .ScriptField("distance", descriptor => descriptor
                    .Source("doc[\u0027location\u0027].arcDistance(params.lat,params.lon)")
                    .Lang("painless")
                    .Params(p => p.Add("lat", lat).Add("lon", lng))))
                    .Query(query => query
                    .Bool(b => b.Filter(allfilters)) &&
                     query.Bool(b => b.Filter(filter => filter
                    .GeoDistance(geo => geo
                    .Field(f => f.Location)
                    .Distance(10, DistanceUnit.Kilometers).Location(lat, lng)
                    .DistanceType(GeoDistanceType.Arc)))
                    .Must(m => m
                    .QueryString(qs => qs
                    .Fields(f => f
                    .Fields(f1 => f1.Title))
                    .Query(searchQuery)))))
                    .Sort(sort => sort
                    .GeoDistance(g => g
                    .Field(f => f.Location)
                    .Order(SortOrder.Ascending)
                    .Points(new GeoLocation(lat, lng))
                    .DistanceType(GeoDistanceType.Arc)
                    )).Source(sr => sr.IncludeAll()));

            var storesArray = stores.Documents?.ToArray();
            var arrayCount = 0;
            foreach (var fieldValues in stores.Fields)
            {
                var distance = fieldValues.Value<double>("distance");
                storesArray[arrayCount].Distance = distance;
                arrayCount++;
            }
            return storesArray?.ToList();