5

I am using Nest, to Query Elasticsearch and I have written this query for my search:

var searchResponse = _elasticClient.Search<AdDocument>(s => s
    .Query(q => q
       .Bool(b => b
          .Must(m => m
             .MultiMatch(mm => mm
                .Fields(f => f.Field(p => p.Title, 1.5).Field(p => p.Description))
                .Query("MyKeyword")
                .Fuzziness(Fuzziness.Auto)
             )
       )
       .Filter(fi => fi
          .Bool(fb => fb
             .Must(m => m.Range(r => r.Field(f => f.NoOfBedrooms == 3)),
                   m => m.Range(r => r.Field(f => f.NoOfBathrooms == 2)),
                   m => m.Range(r => r.Field(f => f.Price > 2000))
             )
          )
       )
    )
  )
);

What I want to achieve is to build this query dynamically, depending on the filters which are passed in. How can I write this query using Object Initializer?

For example, I want to Create those three range filters outside of query and put them in 3 objects, say rangeFilter1, rangeFilter2 and rangeFilter3 and then inside the query use logical AND (&&) to combine them.

1 Answer 1

3

This is the object initializer syntax:

var boolQuery = new BoolQuery
{
  Must = new QueryContainer[]
  {
    new MultiMatchQuery
    {
      Fields = Field<AdDocument>(p => p.Title, 1.5).And<AdDocument>(p => p.Description),
      Query = "MyKeyword",
      Fuzziness = Fuzziness.Auto
    }
  },
  Filter = new QueryContainer[]
  {
    new TermQuery { Field = Field<AdDocument>(f => f.NoOfBedrooms), Value = 3 } &&
    new TermQuery { Field = Field<AdDocument>(f => f.NoOfBathrooms), Value = 2 } &&
    new NumericRangeQuery { Field = Field<AdDocument>(p => p.Price), GreaterThan = 2000 }
  }
};

var searchResponse = _elasticClient.Search<AdDocument>(new SearchRequest<AdDocument>
{
  Query = boolQuery
});

This would result in the following JSON DSL:

{
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "MyKeyword",
            "fuzziness": "AUTO",
            "fields": [
              "title^1.5",
              "description"
            ]
          }
        }
      ],
      "filter": [
        {
          "bool": {
            "must": [
              {
                "term": {
                  "noOfBedrooms": {
                    "value": 3
                  }
                }
              },
              {
                "term": {
                  "noOfBathrooms": {
                    "value": 2
                  }
                }
              },
              {
                "range": {
                  "price": {
                    "gt": 2000.0
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

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