c# - ElasticSearch 结合 Terms 和 Match 查询

标签 c# elasticsearch nest

我已经通过控制台计算出我需要的 elasticsearch 查询,它按预期工作:

                    "query": {
                    "bool": {
                        "must": [
                        { "terms": { "color": ["red", "blue"]
                            }
                        },
                        { "match": { "availability":   "in stock" }} 
                        ]
                    }
               }

我现在需要使用 nest 客户端执行此操作。我目前尝试过:

                nestClient.Search<Item>(
                s => s.From(query.Page).Size(query.PageSize)
                    .Query(
                        q => q.Bool(
                            b => b.Must(
                                ss => ss.Terms(t => t.Field(f => f.Color).Terms<string>(query.Color)),
                                ss => ss.Match(m => m.Field(f => f.Availability == "in stock"))))).TypedKeys(null));

但是在 fiddler 中查看输出的 JSON 时,它似乎忽略了查询并使用:

{"from":0,"size":24}

如果我删除嵌套查询的 match 部分,则输出的 JSON DSL 将正确使用 Terms 查询。

是否可以一次性完成我要查找的内容?

最佳答案

match query 的查询值需要传递给 .Query(...) 方法

var query = new {
    Page = 0,
    PageSize = 10,
    Color = new [] { "red", "yellow" }
};

nestClient.Search<Item>(s => s
    .From(query.Page)
    .Size(query.PageSize)
    .Query(q => q
        .Bool(b => b
            .Must(
                ss => ss.Terms(t => t.Field(f => f.Color).Terms<string>(query.Color)),
                ss => ss.Match(m => m.Field(f => f.Availability).Query("in stock"))
            )
        )
    )
    .TypedKeys(null)
);

这可以使用 operator overloading on the base query type 进一步缩短, 构造一个更简洁的 bool 查询

nestClient.Search<Item>(s => s
    .From(query.Page)
    .Size(query.PageSize)
    .Query(q => q
        .Terms(t => t.Field(f => f.Color).Terms<string>(query.Color)) && q
        .Match(m => m.Field(f => f.Availability).Query("in stock"))
    )
    .TypedKeys(null)
);

两者都会产生以下查询

{
  "from": 0,
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "terms": {
            "color": [
              "red",
              "yellow"
            ]
          }
        },
        {
          "match": {
            "availability": {
              "query": "in stock"
            }
          }
        }
      ]
    }
  }
}

此外,使用 term-level queriesterms 查询一样,查询的答案通常是"is"或“否”,例如这个术语是否完全匹配,这个数字是否在这个数字范围内,等等。使用这样的谓词,您通常不需要为这些查询执行相关性评分阶段,您可以通过让它们在 filter 上下文,例如 bool 查询的 filter 子句。将其与运算符重载放在一起

nestClient.Search<Item>(s => s
    .From(query.Page)
    .Size(query.PageSize)
    .Query(q => q
        .Terms(t => t.Field(f => f.Color).Terms<string>(query.Color)) && +q
        .Match(m => m.Field(f => f.Availability).Query("in stock"))
    )
    .TypedKeys(null)
);

产生

{
  "from": 0,
  "size": 10,
  "query": {
    "bool": {
      "must": [
        {
          "terms": {
            "color": [
              "red",
              "yellow"
            ]
          }
        }
      ],
      "filter": [
        {
          "match": {
            "availability": {
              "query": "in stock"
            }
          }
        }
      ]
    }
  }
}

关于c# - ElasticSearch 结合 Terms 和 Match 查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51703285/

相关文章:

c# - MVC 5 MultiSelectList 选定值不起作用

python - 请求错误: TransportError(400, 'parse_exception', 'No processor type exists with name[attachment]')

elasticsearch - ElasticSearch.Net无法识别ElasticSearch返回的时间戳

c# - 将null设置为文档属性,并在更新时从数据库中删除字段

c# - NEST Elasticsearch如何将字段与许多值匹配

c# - 我可以在收听模式下启动语音识别器并且对用户不可见吗?

c# 模拟接口(interface) vs 模拟类

c# - Response.TransmitFile() 的替代品

java - 密码更改后ElasticSearch连接状态

php - laravel elasticsearch babenkoivan/elastic-adapter模型关系