Elasticsearch geodistance range

С обновлением ElasticSearch (с 2.x до 6.3) мы потеряли возможность использования минимального максимального диапазона для нашего поиска.

Раньше мы использовали это для создания «Пончикового поиска». Мы не хотели, чтобы объекты находились слишком близко друг к другу, а были между диапазонами.

Просто исследую, есть ли какой-либо способ сделать это в новой версии. Просмотрел документы и не нашел ничего, что могло бы помочь.

f.GeoDistanceRange(x => x
Field(s => s.GeoLocation)
.Location(new Nest.GeoLocation(filter.SubjectLatitude.Value, 
filter.SubjectLongitude.Value))
.GreaterThanOrEqualTo(Nest.Distance.Kilometers(_distanceMin))
.LessThanOrEqualTo(Nest.Distance.Kilometers(_distanceMax)));

Подойдет ли для вашего варианта использования агрегирование Geo Distance с вложенным агрегированием Top Hits?

Russ Cam 26.10.2018 09:31

Спасибо, Расс, именно то, что мне нужно было использовать.

Josh McInnes 12.11.2018 00:15

Рад помочь :)

Russ Cam 12.11.2018 01:14
0
3
149
1

Ответы 1

Агрегация GeoDistance с вложенной агрегацией лучших совпадений была решением, как предложил Расс Кэм. (Примечание: диапазоны linq есть, поэтому я ищу только нужное мне ведро, в зависимости от того, какие минимальные / максимальные значения были введены (включая нули)

        if (_isSubjectGeocoded && (filter.DistanceMax.HasValue || filter.DistanceMin.HasValue))
        {
             search = search.Aggregations(a =>
             a.GeoDistance("sale_geo_distance_agg", g =>
             g.Field(s => s.GeoLocation)
             .Origin(filter.SubjectLatitude.Value, filter.SubjectLongitude.Value)
             .Unit(Nest.DistanceUnit.Kilometers)
             .Ranges(
                     r => !filter.DistanceMin.HasValue ? 
                                  r.To(_distanceMax) : 
                                  !filter.DistanceMax.HasValue ?                         
                                        r.From(_distanceMin) : 
                                           r.From(_distanceMin).To(_distanceMax)
              ).Aggregations(top => 
              top.TopHits("top_geodistance_hits", hits => hits
              .Size(_take)
              .From(_skip))))
         );
     }

Мне нужно было применить это позже с

        if (_isSubjectGeocoded && (filter.DistanceMax.HasValue || filter.DistanceMin.HasValue))
        {
            var _geoBuckets = _sales.Aggregations.GeoDistance("sale_geo_distance_agg").Buckets;
            Nest.RangeBucket _bucket = _geoBuckets.First();
            _totalCount = (int)_bucket.DocCount;
            var _bucketHits = _bucket.TopHits("top_geodistance_hits").Documents<SaleSearch>().Select(x => x.SaleId);
            _saleDocuments = _saleDocuments.Where(s => _bucketHits.Contains(s.SaleId)).Select(s => s);
        }

Моя единственная проблема после этого заключалась в том, что изначально у нас были ограничения на количество страниц 25/50/100/200/500. Теперь, когда я реализовал топ-хиты, я снижаю его до 25/50/100, поскольку топ-хиты поддерживают только до 100 без необходимости изменения настроек в эластичном (плюс это в любом случае для нас излишне. Пейджинг всегда работает)

Надеюсь, это поможет всем, кто с этим сталкивается. Хотя немного побродил: D

Другие вопросы по теме