ElasticSearch: создание запросов на основе динамического c списка критериев с помощью NEST - PullRequest
0 голосов
/ 29 мая 2020

Используя ElasticSearch 7.6, я хочу найти все точки, которые находятся внутри списка областей. Есть несколько других критериев фильтрации, которые добавляются в список QueryContainerDescriptors и применяются к окончательному поиску.

 var queries = new List<Func<QueryContainerDescriptor<MySearchableObject>, QueryContainer>>();

Этот пример работает для одной области, где Координаты - это словарь

foreach (var area in areas)
{
    var pointsList = area.Coordinates.Values.Select(p => new GeoLocation(p.Latitude, p.Longitude)).ToList();

    queries.Add(sqs => sqs
        .GeoPolygon(r => r
            .Field(f => f.Position)
            .ValidationMethod(GeoValidationMethod.Strict)
            .Points(pointsList)));
}

а также это:

queries.Add(sqs => sqs.Bool(b=>b.Should(bs => GeoPolygonShouldQuery(bs, area))));

private static QueryContainer GeoPolygonShouldQuery(QueryContainerDescriptor<MySearchableObject> bs, FilterArea area)
{
     return bs
    .GeoPolygon(r => r
        .Field(f => f.Position)
        .ValidationMethod(GeoValidationMethod.Strict)
        .Points(area.Coordinates.Values.Select(p => new GeoLocation(p.Latitude, p.Longitude))));
}

Как мне добавить предложение should для каждой области в списке?

Подобно этому:

queries.Add(sqs => sqs.Bool(b => b.Should(
                bs => bs.GeoPolygon(r => r.Field(f => f.Position)
                    .Points(areas.ElementAt(0).Coordinates.Values.Select(p => new GeoLocation(p.Latitude, p.Longitude)).ToList())),
                bs => bs.GeoPolygon(r => r.Field(f => f.Position)
                    .Points(areas.ElementAt(1).Coordinates.Values.Select(p => new GeoLocation(p.Latitude, p.Longitude)).ToList()))
                )));

1 Ответ

0 голосов
/ 29 мая 2020

После еще немного проб и ошибок. похоже, это решает проблему:

var areas = FindFilterAreas(query.Areas);
queries.Add(sqs => sqs.Bool(b => b.Should(MyQueries(b, areas))));

private static List<Func<QueryContainerDescriptor<SearchableSituation>, QueryContainer>> MyQueries(BoolQueryDescriptor<SearchableSituation> qd, IEnumerable<FilterArea> areas)
{
    List<Func<QueryContainerDescriptor<SearchableSituation>, QueryContainer>> queries = new List<Func<QueryContainerDescriptor<SearchableSituation>, QueryContainer>> { };
    foreach (var area in areas)
    {
        var pointsList = area.Coordinates.Values.Select(p => new GeoLocation(p.Latitude, p.Longitude)).ToList();

        queries.Add(sqs => sqs
            .GeoPolygon(r => r
                .Field(f => f.Position)
                .ValidationMethod(GeoValidationMethod.Strict)
                .Points(pointsList)));
    }    

return queries;

}

...