0
votes

I wrote this ElasticSearch query to find aggregation count of terms in indexed data.

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
            }
          }
        }
      ]
    }
  }
}

This query is created for search term 'apple orange banana'. So, there are three named filters. But if user searches for 'apple orange banana grape' there should be for named filters. I want to insert it using NEST.

Below is the code I have implemented to create named filters as per 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" });
}

Now, Problem is I'm using Fluent DSL to execute query in ElasticSearch and I don't know how to add myFilters in it. Can anyone help?

Any kind of help would be great for me!

Thanks in advance.

1

1 Answers

1
votes

Assuming, that words variable contain required names and terms, here is the result NEST query

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()
                    )
                )
            )
        )
    )
);

I've also removed root must condition since it doesn't make sence for a single condition