1

Can you suggest how do I build a query based on multiple filter. Currently, I want to implement a search functionality using the following filters:

  • ProductName
  • Countries (array)
  • Cities (array)

The requirements is that, when counties or cities has no selected value, the query assumes that you are searching all countries and cities. If there are selected counties and cities, then the result should be base on the selected counties and cities.

I have the query below to start with.

static void Main(string[] args)
{   
    var uri = new Uri("http://localhost:9200");
    var connectionPool = new SingleNodeConnectionPool(uri);
    var settings = new ConnectionSettings(connectionPool);

    var client = new ElasticClient(settings);

    if (counties.Count > 0) 
    {
        foreach(string country in counties)
        {
            // Add a query to be added in client.Search     
        }
    }

    if (cities.Count > 0)
    {
        foreach(string city in cities)
        {
            // Add a query to be added in client.Search
        }
    }

    client.Search<Product>(s => s
                            .Query(q => q
                                .Bool(b => b
                                    .Must(mu => mu
                                        .Match(m => m
                                            .Field(f => f.ProductName)
                                            .Query("some text")
                                        ),
                                        .
                                    )
                                )
                            )
                        );
}
2
  • Do you have fields for cities and for countries? What do they contain? Commented Apr 27, 2017 at 12:13
  • Yes. The field is Country and City and datatype is string. Commented Apr 27, 2017 at 12:56

2 Answers 2

2

I just answer my own question. Currently, I came with this approach.

var sd = new SearchDescriptor<object>();
var qc = new QueryContainer();
var qd = new QueryContainerDescriptor<object>();

sd.From(0);
sd.Size(100);
sd.Index("Products");
sd.Type("Product");

if (!string.IsNullOrEmpty(title))
{
    qc = qd.Match(m1 => m1
        .Field("title")
        .Query(title)
    );
}

if (countries.Count > 0)
{
    qc = qd.Terms(t => t
            .Field("country")
            .Terms(countries.ToArray())
        );
}

if (cities.Count > 0)
{
    qc = qd.Terms(t => t
            .Field("city")
            .Terms(cities.ToArray())
        );
}

sd.Query(q => q
        .Bool(b => b
            .Must(qc)
        )
    );

var result = client.Search<object>(s => s = sd);
Sign up to request clarification or add additional context in comments.

Comments

1

You can use the terms query:

{
  "query": {
    "bool": {
      "must": [
        { "match": { "field": "productName", "query": "some text"}},
        // Only add this filter if the array is not empty
        { "terms": { "Country": ["Canada", "France"]}},
        // Same here
        { "terms": { "City": ["Ottawa", "Paris"]}},
      ]
    }
  }
}

2 Comments

Thanks! Will try to convert it using NEST 😃
NEST reference documentation for terms query: elastic.co/guide/en/elasticsearch/client/net-api/current/…

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.