在Elastic Search NEST中的主MultiMatch查询后应用不同的过滤器

时间:2016-07-31 11:36:12

标签: c# elasticsearch nest

所以,这是我的问题:

_elasticClient.Search<SearchItem>(x =>
                x.Sort(sort).Size(itemsPerPage)
                .Query(q =>
                    q.MultiMatch(m => m
                    .Fields(fs => fs
                        .Field(p => p.Field1)
                        .Field(p => p.Field2)
                        .Field(p => p.Field3)
                        .Field(p => p.Field4)
                        .Field(p => p.Field5)
                        .Field(p => p.Field6)                            
                    )
                    .Operator(Operator.And)
                    .Query(pattern)
                )));

我必须应用不同的过滤器。范围过滤器(价格),过滤结果集,其中field1 =“Audi”,field2 =“Sale Car”。我试着这样做:

.Query(q =>
                    q.MultiMatch(m => m
                    .Fields(fs => fs
                        Field(p => p.Field1)
                            .Field(p => p.Field2)
                            .Field(p => p.Field3)
                            .Field(p => p.Field4)
                            .Field(p => p.Field5)
                            .Field(p => p.Field6)  
                    )
                    .Operator(Operator.And)
                    .Query(pattern)))
.Query(q=>q.Range(ra=>ra.Field(ff=>ff.SalePrice).GreaterThan(1000))));

但这不起作用。我的所有结果来自索引,价格大于1000,但只需搜索结果。有谁可以帮助我?

1 个答案:

答案 0 :(得分:1)

您可以 use a bool query to combine queries ,NEST通过重载运算符来组合QueryContainer(根查询类型),使其更容易使用。这是NEST 2.x

的一个例子
void Main()
{
    var connectionPool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
    var settings = new ConnectionSettings(connectionPool);

    var client = new ElasticClient(settings);

    var itemsPerPage = 20;
    var pattern = "match query";

    client.Search<SearchItem>(x => x
        .Sort(so => so
            .Descending("_score")
        )
        .Size(itemsPerPage)
        .Query(q => q
            .MultiMatch(m => m
                .Fields(fs => fs
                    .Field(p => p.Field1)
                    .Field(p => p.Field2)
                    .Field(p => p.Field3)
                    .Field(p => p.Field4)
                    .Field(p => p.Field5)
                    .Field(p => p.Field6)
                )
                .Operator(Operator.And)
                .Query(pattern)
            ) && q
            .Range(ra => ra
                .Field(ff=>ff.SalePrice)
                .GreaterThan(1000)
            )
        )
    );
}

public class SearchItem
{
    public int SalePrice { get; set; }

    public string Field1 { get; set; }

    public string Field2 { get; set; }

    public string Field3 { get; set; }

    public string Field4 { get; set; }

    public string Field5 { get; set; }

    public string Field6 { get; set; }
}

产生

{
  "size": 20,
  "sort": [
    {
      "_score": {
        "order": "desc"
      }
    }
  ],
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "match query",
            "operator": "and",
            "fields": [
              "field1",
              "field2",
              "field3",
              "field4",
              "field5",
              "field6"
            ]
          }
        },
        {
          "range": {
            "salePrice": {
              "gt": 1000.0
            }
          }
        }
      ]
    }
  }
}

这将找到与multi_match查询匹配的文档,而salePrice也大于1000.因为我们不需要计算得分对于范围查询(文档的salePrice大于1000或它没有),范围查询可以在过滤器上下文中运行。一个稍微精炼的版本

client.Search<SearchItem>(x => x
    .Sort(so => so
        .Descending("_score")
    )
    .Size(itemsPerPage)
    .Query(q => q
        .MultiMatch(m => m
            .Fields(fs => fs
                .Field(p => p.Field1)
                .Field(p => p.Field2)
                .Field(p => p.Field3)
                .Field(p => p.Field4)
                .Field(p => p.Field5)
                .Field(p => p.Field6)
            )
            .Operator(Operator.And)
            .Query(pattern)
        ) && +q
        .Range(ra => ra
            .Field(ff=>ff.SalePrice)
            .GreaterThan(1000)
        )
    )
);

将一元+运算符附加到范围查询是bool查询过滤器的简写。查询json现在看起来像

{
  "size": 20,
  "sort": [
    {
      "_score": {
        "order": "desc"
      }
    }
  ],
  "query": {
    "bool": {
      "must": [
        {
          "multi_match": {
            "query": "match query",
            "operator": "and",
            "fields": [
              "field1",
              "field2",
              "field3",
              "field4",
              "field5",
              "field6"
            ]
          }
        }
      ],
      "filter": [
        {
          "range": {
            "salePrice": {
              "gt": 1000.0
            }
          }
        }
      ]
    }
  }
}