在Elasticsearch中构建多个过滤器

时间:2017-04-27 11:40:16

标签: elasticsearch nest elasticsearch-net

您能否建议如何基于多个过滤器构建查询? 目前,我想使用以下过滤器实现搜索功能:

  • 产品名称
  • 国家/地区(数组)
  • 城市(数组)

要求是,当县或城市没有选定值时,查询会假定您正在搜索所有国家/地区和城市。 如果选择了县和城市,那么结果应该基于所选择的县和城市。

我从下面开始查询。

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 个答案:

答案 0 :(得分:1)

您可以使用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"]}},
      ]
    }
  }
}

答案 1 :(得分:0)

我只是回答我自己的问题。目前,我采用了这种方法。

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