0

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 Answer 1

1

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

Sign up to request clarification or add additional context in comments.

1 Comment

Learned some new things from your answer! Helped a lot!!! Thanks @Random

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.