user9610034
user9610034

Reputation:

Building a dynamic query using object initializer syntax

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.

Upvotes: 5

Views: 1358

Answers (1)

Hooman Bahreini
Hooman Bahreini

Reputation: 15559

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

Upvotes: 3

Related Questions