将具有命名过滤器的ElasticSearch聚合查询转换为NEST C#

时间:2017-05-06 13:12:09

标签: c# search elasticsearch nest elasticsearch-dsl

我编写了这个ElasticSearch查询,以查找索引数据中术语的聚合计数。

SearchTerm:apple orange banana

{
  "size": 0,
  "_source": {
    "excludes": [
      "chapterData"
    ]
  },
  "aggs": {
    "asPerBookID": {
      "terms": {
        "field": "bookID",
        "size": 100000
      },
      "aggs": {
        "asPerChapterIndex": {
          "terms": {
            "field": "chapterIndex",
            "min_doc_count": 1,
            "size": 10000
          },
          "aggs": {
            "asPerChapterData": {
              "nested": {
                "path": "chapterData"
              },
              "aggs": {
                "asPerChapterDatadotData": {
                  "filters": {
                    "filters": {
                      "apple": {
                        "query_string": {
                          "query": "apple",
                          "default_field": "chapterData.data"
                        }
                      },
                      "orange": {
                        "query_string": {
                          "query": "orange",
                          "default_field": "chapterData.data"
                        }
                      },
                      "banana": {
                        "query_string": {
                          "query": "banana",
                          "default_field": "chapterData.data"
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "query": {
    "bool": {
      "must": [
        {
          "nested": {
            "query": {
              "bool": {
                "should": [
                  {
                    "query_string": {
                      "query": "apple",
                      "default_field": "chapterData.data"
                    }
                  },
                  {
                    "query_string": {
                      "query": "orange",
                      "default_field": "chapterData.data"
                    }
                  },
                  {
                    "query_string": {
                      "query": "banana",
                      "default_field": "chapterData.data"
                    }
                  }
                ],
                "minimum_number_should_match": 1
              }
            },
            "path": "chapterData",
            "inner_hits": {
              "size": 10000
            }
          }
        }
      ]
    }
  }
}

此查询是针对搜索字词'apple orange banana'创建的。因此,有三个命名过滤器。但如果用户搜索“苹果橙香蕉葡萄”,应该有命名过滤器。我想用NEST插入它。

以下是我根据SearchTerm创建命名过滤器的代码。

string[] words = pSearchTerm.Split(' ');
NamedFiltersContainer myFilters = new NamedFiltersContainer();
foreach (var str in words)
{
      myFilters.Add(str, new QueryStringQuery() { Query = str, DefaultField = "chapterData.data", DefaultOperator = lOperator, Analyzer = "whitespace" });
}

现在,问题是我使用Fluent DSL在ElasticSearch中执行查询,我不知道如何在其中添加myFilters。有人可以帮忙吗?

任何形式的帮助对我来说都很棒!

提前致谢。

1 个答案:

答案 0 :(得分:1)

假设words变量包含必需的名称和术语,这里是结果NEST查询

client.Search<Sample>(search => search
    .Size(0)
    .Source(
        source => source.Excludes(
            excludes => excludes.Field(i => i.ChapterData)
        )
    ).Aggregations(aggs => aggs
        .Terms("asPerBookID", terms => terms
            .Field(i => i.BookID)
            .Aggregations(bookIDAggs => bookIDAggs
                .Nested("asPerChapterData", nested => nested
                    .Path(i => i.ChapterData)
                    .Aggregations(chapterDataAggs => chapterDataAggs
                        .Filters("asPerChapterDatadotData", filters => filters
                            .NamedFilters(named => words
                                .Aggregate(named, (_named, word) => _named
                                    .Filter(word, filter => filter
                                        .QueryString(queryString => queryString
                                            .Query(word)
                                            .DefaultField("chapterData.data")
                                        )
                                    )
                                )
                            )
                        )
                    )
                )
            )
        )
    ).Query(query => query
        .Nested(nested => nested
            .Path(i => i.ChapterData)
            .Query(nestedQuery => nestedQuery
                .Bool(boolean => boolean
                    .Should(words
                        .Select(word => (QueryContainer)new QueryStringQuery
                        {
                            Query = word,
                            DefaultField = "chapterData.data"
                        }).ToArray()
                    )
                )
            )
        )
    )
);

我还删除了根must条件,因为它没有针对单一条件进行查看