Elasticsearch特定领域的完全匹配

时间:2018-08-22 19:32:36

标签: elasticsearch

使用

$ docker run -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" docker.elastic.co/elasticsearch/elasticsearch:6.3.2

填充数据库

$ curl -X PUT "localhost:9200/my_index/my_type/1" -H 'Content-Type: application/json' -d'
{
  "text": "foo bar"
}
'

$ curl -X PUT "localhost:9200/my_index/my_type/2" -H 'Content-Type: application/json' -d'
{
  "text":   "baz quix"
}
'

验证是否填充了数据库

$ curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
  "query": {
    "match_all": {}
  }
}'

{"took":48,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":2,"max_score":1.0,"hits":[{"_index":"my_index","_type":"my_type","_id":"2","_score":1.0,"_source":
{
  "text":   "baz quix"
}
},{"_index":"my_index","_type":"my_type","_id":"1","_score":1.0,"_source":
{
  "text": "foo bar"
}
}]}}

constant_score返回[],尽管期望返回ID为2的对象

$ curl -X GET "localhost:9200/my_index/my_type/_search" -H 'Content-Type: application/json' -d'
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "text":"baz quix"
        }
      }
    }
  }
}'

{"took":14,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}
完全不支持

filtered

$ curl -X GET "localhost:9200/my_index/my_type/_search" -H 'Content-Type: application/json' -d'
{
  "query": {
    "filtered": {
      "filter": {
        "term": {
          "text":"baz quix"
        }
      }
    }
  }
}'

{"error":{"root_cause":[{"type":"parsing_exception","reason":"no [query] registered for [filtered]","line":4,"col":17}],"type":"parsing_exception","reason":"no [query] registered for [filtered]","line":4,"col":17},"status":400}

没有constant_score的搜索都无法正常工作

$ curl -X GET "localhost:9200/my_index/my_type/_search" -H 'Content-Type: application/json' -d'
{
  "query": {
    "term": {
      "text":"baz quix"
    }
  }
}'

{"took":1,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}

$ curl -X GET "localhost:9200/_search" -H 'Content-Type: application/json' -d'
{
  "query": {
    "term": {
      "text":"baz quix"
    }
  }
}'

{"took":3,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":0,"max_score":null,"hits":[]}}

1 个答案:

答案 0 :(得分:1)

首先,检查索引的映射:

$ curl -X GET -H 'Content-Type: application/json' -i 'http://localhost:9200/my_index/_mapping'

{
  "my_index": {
    "mappings": {
      "my_type": {
        "properties": {
          "text": {
            "type": "text",
            "fields": {
              "keyword": {
                "type": "keyword",
                "ignore_above": 256
              }
            }
          }
        }
      }
    }
  }
}

在该输出中,您可以看到默认情况下,Elasticsearch将您的字段映射两次:它使用"text"创建名为"type": "text"的字段,并使用"text.keyword"创建名为"type": "keyword"的嵌套字段。

类型为text的字段是全文字段,索引时为analyzed的数据,而类型为keyword的字段将其数据“按原样”保留在索引中,而无需进行分析。 / p>

因此,对于术语查询,您必须使用类型为keyword的嵌套字段:

$ curl -X GET "localhost:9200/my_index/my_type/_search" -H 'Content-Type: application/json' -d'
{
  "query": {
    "constant_score": {
      "filter": {
        "term": {
          "text.keyword": "baz quix"
        }
      }
    }
  }
}'

{"took":3,"timed_out":false,"_shards":{"total":5,"successful":5,"skipped":0,"failed":0},"hits":{"total":1,"max_score":1.0,"hits":[{"_index":"my_index","_type":"my_type","_id":"2","_score":1.0,"_source":{"text":"baz quix"}}]}}

您还可以阅读“为什么查询字词不匹配我的文档?”部分。 official documentation中的内容,也提供了清晰的解释。