Как с помощью Nest Fluent DSL создать отфильтрованную вложенную агрегацию? - PullRequest
0 голосов
/ 10 июля 2020

У меня есть следующий запрос ElasticSearch:

{
  "size": 0,
  "aggs": {
    "product_attribute_nested_agg": {
      "nested": {
        "path": "productAttributes"
      },
      "aggs": {
        "inner": {
          "filter": {
            "fuzzy": {
              "productAttributes.name": {
                "value": "SS",
                "fuzziness": 3
              }
            }
          },
          "aggs": {
            "terms_nested_agg": {
              "terms": {
                "field": "productAttributes.name"
              }
            }
          }
        }
      }
    }
  }
}

Я использую Nest в качестве клиентской библиотеки, и вот как я генерирую вложенный агрегационный запрос с помощью Fluent DSL:

var searchResponse = elasticClient.Search<ProductType>(s => s
                    .Index(indices)
                    .Type(Types.Type(typeof(ProductType)))
                    .Size(0)
                    .Aggregations(a => a
                         .Nested("product_attribute_nested_agg", n => n
                             .Path(Infer.Field<ProductType>(ff => ff.ProductAttributes))
                             .Aggregations(aa => aa
                                 .Terms("terms_nested_agg", t => t
                                     .Field(p => p.ProductAttributes.Suffix("name"))
                                 )
                             )
                         )
                    )
                );

Но как можно Я генерирую внутренний фильтр, используя синтаксис Fluent DSL ?

1 Ответ

0 голосов
/ 10 июля 2020

После некоторого исследования и поиска мне удалось сгенерировать отфильтрованную вложенную агрегацию с использованием Nest fluent DSL:

       var searchResponse = elasticClient.Search<ProductType>(s => s
                            .Index(indices)
                            .Type(Types.Type(typeof(ProductType)))
                            .Size(0)
                            .Aggregations(a => a
                                .Nested("product_attribute_nested_agg", n => n
                                   .Path(Infer.Field<ProductType>(ff => ff.ProductAttributes))
                                   .Aggregations(a1 => a1
                                     .Filter("inner", ia => ia
                                        .Filter(f => f
                                              .Fuzzy(fuzzy => fuzzy
                                                   .Field(Infer.Field<ProductType>(ff => ff.ProductAttributes.First().Name))
                                                   .Value(productAttribute)
                                                   .Fuzziness(Fuzziness.EditDistance(3))
                                               )
                                         ).Aggregations(na => na
                                            .Terms("terms_nested_agg", t => t
                                              .Field(p => p.ProductAttributes.Suffix("name"))
                                            )
                                         )
                                     )               
                                  )
                               )
                           )
                      );


    var result = new List<ProductAttributesSuggestionResult>();

    var nestedAgg = searchResponse.Aggregations.Nested("product_attribute_nested_agg");
    var inner = (SingleBucketAggregate)nestedAgg.Values.FirstOrDefault();
    var termsAgg = inner.Terms("terms_nested_agg");
    foreach (var bucket in termsAgg.Buckets)
    {
        result.Add(new ProductAttributesSuggestionResult
        {
            Name = bucket.Key,
            ProductsCount = bucket.DocCount ?? 0
        });
    }

Надеюсь, мой ответ поможет другим, у которых есть такая же проблема.

...