【问题标题】:Elastic Search : Match Query not working in Nested Bool Filters弹性搜索:匹配查询在嵌套布尔过滤器中不起作用
【发布时间】:2015-10-31 17:59:43
【问题描述】:

我能够获取以下弹性搜索查询的数据:

{
  "query": {
    "filtered": {
      "query": [],
      "filter": {
        "bool": {
          "must": [
            {
              "bool": {
                "should": [
                  {
                    "term": {
                      "gender": "malE"
                    }
                  },
                  {
                    "term": {
                      "sentiment": "positive"
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    }
  }
}

但是,如果我使用“匹配”进行查询 - 我会收到带有 400 状态响应的错误消息

{
  "query": {
    "filtered": {
      "query": [],
      "filter": {
        "bool": {
          "must": [
            {
              "bool": {
                "should": [
                  {
                    "match": {
                      "gender": "malE"
                    }
                  },
                  {
                    "term": {
                      "sentiment": "positive"
                    }
                  }
                ]
              }
            }
          ]
        }
      }
    }
  }
}

嵌套布尔过滤器不支持匹配查询吗?

由于术语查询在字段的倒排索引中查找确切的术语,并且我想将性别数据查询为不区分大小写的字段 - 我应该尝试哪种方法?

索引设置:

{
  "settings": {
    "index": {
      "analysis": {
        "analyzer": {
          "analyzer_keyword": {
            "tokenizer": "keyword",
            "filter": "lowercase"
          }
        }
      }
    }
  }
}

字段性别映射:

{"type":"string","analyzer":"analyzer_keyword"}

【问题讨论】:

  • 如果您花费太多时间,索引小写属性可能会更容易
  • @johnSmith 我没听懂你。你的意思是我应该在通过术语查询搜索之前将属性设为小写?
  • 我的意思是你很可能索引对象并有一个用于弹性搜索的映射,你可以简单地向你的对象类添加一个属性和一个 getter 函数来返回小写名称,将此字段添加到弹性映射和你没有问题
  • 我认为清理将被索引的字段是有意义的,因此最终应该触及 searchenginge 的整体性能
  • 谢谢。我正在清理该字段并在搜索之前将术语小写(例如:{“term”:{“gender”:[“male”]})。正在寻找另一种方法

标签: elasticsearch


【解决方案1】:

您收到错误 400 的原因是因为没有 match 过滤器,只有 match queries,即使有 term queriesterm filters

您的查询可以像这样简单,即不需要filtered 查询,只需将您的termmatch 查询放入bool/should

{
  "query": {
    "bool": {
      "should": [
        {
          "match": {
            "gender": "male"
          }
        },
        {
          "term": {
            "sentiment": "positive"
          }
        }
      ]
    }
  }
}

【讨论】:

  • 谢谢。我虽然匹配将在过滤器 dsl 中工作,因为我使用的是/否输出。除了上述之外,我应该使用哪种方法进行不区分大小写的搜索 - 例如,“情绪”字段中的“非常积极”的 aggs。提交的情绪包含 ["positive","very positive","negative","verynegative"]
【解决方案2】:

此答案适用于 ElasticSearch 7.x。正如我从问题中了解到的那样,您想对gender 字段使用匹配查询,对sentiment 字段使用术语查询。每个字段的映射应如下所示:

"sentiment": { 
       "type": "keyword" 
},
"gender": {
      "type": "text" 
}

相应的搜索 API 将是:

"query": {
        "bool": {
            "must": [
                {
                    "terms": {
                        "sentiment": [
                            "very positive", "positive"
                        ]
                    }
                },
                {
                    "match": {
                        "gender": "malE"
                    }
                }
            ]
        }
    }

此搜索 API 返回所有性别为“Male”/“MALE”/“mALe”等的文档。因此,您可能已经索引了包含“mALe”的性别字段,但是, "gender": "malE" 的匹配查询将仍然可以检索它。在最新版本的 ElasticSearch 中,如果查询是 match 类型,则在开始搜索之前,值(即 "gender": "malE")将在内部自动小写。但是,对于 API 的客户端来说,在开始时将小写字母传递给匹配查询应该不是那么困难。来到sentiment 字段,因为它是keyword 字段,您可以搜索包含空格的值,例如very positive

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-17
    • 1970-01-01
    • 2020-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多