elasticsearch 在Elasticsearch的所有字段中按精确匹配进行搜索,elasticsearch,exact-match,elasticsearch,Exact Match" /> elasticsearch 在Elasticsearch的所有字段中按精确匹配进行搜索,elasticsearch,exact-match,elasticsearch,Exact Match" />

elasticsearch 在Elasticsearch的所有字段中按精确匹配进行搜索

elasticsearch 在Elasticsearch的所有字段中按精确匹配进行搜索,elasticsearch,exact-match,elasticsearch,Exact Match,假设我有3个文档,每个文档只包含一个字段(但假设还有更多文档,我们需要搜索所有字段) 字段值为“第一秒” 字段值为“第二优先” 字段值为“第一个第二个第三个” 以下是可用于创建这3个文档的脚本: # drop the index completely, use with care! curl -iX DELETE 'http://localhost:9200/test' curl -H 'content-type: application/json' -iX PUT 'http://local

假设我有3个文档,每个文档只包含一个字段(但假设还有更多文档,我们需要搜索所有字段)

  • 字段值为“第一秒”
  • 字段值为“第二优先”
  • 字段值为“第一个第二个第三个”
  • 以下是可用于创建这3个文档的脚本:

    # drop the index completely, use with care!
    curl -iX DELETE 'http://localhost:9200/test'
    
    curl -H 'content-type: application/json' -iX PUT 'http://localhost:9200/test/_doc/one' -d '{"name":"first second"}'
    curl -H 'content-type: application/json' -iX PUT 'http://localhost:9200/test/_doc/two' -d '{"name":"second first"}'
    curl -H 'content-type: application/json' -iX PUT 'http://localhost:9200/test/_doc/three' -d '{"name":"first second third"}'
    
    我需要找到唯一一个在其中一个字段中有“first second”文本的文档(文档1)

    这是我试过的

    A.普通搜索:

    curl -H 'Content-Type: application/json' -iX POST 'http://localhost:9200/test/_search' -d '{
      "query": {
        "query_string": {
          "query": "first second"
        }
      }
    }'
    
    返回所有3个文档

    B.引用

    curl -H 'Content-Type: application/json' -iX POST 'http://localhost:9200/test/_search' -d '{
      "query": {
        "query_string": {
          "query": "\"first second\""
        }
      }
    }'
    
    给出2个文档:1和3,因为它们都包含“first second”

    在这里,他们建议在索引时使用“关键字”分析器来分析字段,但我希望避免对映射进行任何自定义


    是否可以避免它们,但仍然只能找到文档1?

    是的,您可以通过将
    名称
    映射类型声明为
    关键字
    来实现这一点。解决问题的关键很简单——声明
    name
    mapping
    type:keyword
    然后离开

    为了证明这一点,我已经做了这些

    1) created mapping with `keyword` for `name` field`
    2) indexed the three documents
    3) searched with a `match` query
    
    映射

    PUT so_test16
    {
      "mappings": {
        "_doc":{
          "properties":{
            "name": {
              "type": "keyword"
    
            }
          }
        }
      }
    }
    
    POST /so_test16/_doc
    {
        "id": 1,
        "name": "first second"
    }
    POST /so_test16/_doc
    {
        "id": 2,
        "name": "second first"
    }
    
    POST /so_test16/_doc
    {
        "id": 3,
        "name": "first second third"
    }
    
    PUT so_test18
    {
    
        "mappings" : {
          "_doc" : {
            "properties" : {
              "id" : {
                "type" : "long"
              },
              "name" : {
                "type" : "text",
                "fielddata": true
              }
            }
          }
    
      }
    }
    
    为文档编制索引

    PUT so_test16
    {
      "mappings": {
        "_doc":{
          "properties":{
            "name": {
              "type": "keyword"
    
            }
          }
        }
      }
    }
    
    POST /so_test16/_doc
    {
        "id": 1,
        "name": "first second"
    }
    POST /so_test16/_doc
    {
        "id": 2,
        "name": "second first"
    }
    
    POST /so_test16/_doc
    {
        "id": 3,
        "name": "first second third"
    }
    
    PUT so_test18
    {
    
        "mappings" : {
          "_doc" : {
            "properties" : {
              "id" : {
                "type" : "long"
              },
              "name" : {
                "type" : "text",
                "fielddata": true
              }
            }
          }
    
      }
    }
    
    查询

    GET /so_test16/_search
    {
      "query": {
        "match": {"name": "first second"}
      }
    }
    
    和结果

    {
      "took" : 1,
      "timed_out" : false,
      "_shards" : {
        "total" : 5,
        "successful" : 5,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : 1,
        "max_score" : 0.2876821,
        "hits" : [
          {
            "_index" : "so_test16",
            "_type" : "_doc",
            "_id" : "m1KXx2sB4TH56W1hdTF9",
            "_score" : 0.2876821,
            "_source" : {
              "id" : 1,
              "name" : "first second"
            }
          }
        ]
      }
    }
    
    添加第二个解决方案 (如果
    名称
    不是
    关键字
    类型,而是
    文本
    类型。这里只有
    字段数据:
    名称
    字段也需要添加true

    映射

    PUT so_test16
    {
      "mappings": {
        "_doc":{
          "properties":{
            "name": {
              "type": "keyword"
    
            }
          }
        }
      }
    }
    
    POST /so_test16/_doc
    {
        "id": 1,
        "name": "first second"
    }
    POST /so_test16/_doc
    {
        "id": 2,
        "name": "second first"
    }
    
    POST /so_test16/_doc
    {
        "id": 3,
        "name": "first second third"
    }
    
    PUT so_test18
    {
    
        "mappings" : {
          "_doc" : {
            "properties" : {
              "id" : {
                "type" : "long"
              },
              "name" : {
                "type" : "text",
                "fielddata": true
              }
            }
          }
    
      }
    }
    
    和搜索查询

    GET /so_test18/_search
    {
      "query": {
        "bool": {
          "must": [
            {"match_phrase": {"name": "first second"}}
          ],
          "filter": {
    
            "script": {
              "script": {
                "lang": "painless",
                "source": "doc['name'].values.length == 2"
              }
            }
    
          }
        }
    
      }
    }
    
    和响应

    {
      "took" : 3,
      "timed_out" : false,
      "_shards" : {
        "total" : 5,
        "successful" : 5,
        "skipped" : 0,
        "failed" : 0
      },
      "hits" : {
        "total" : 1,
        "max_score" : 0.3971361,
        "hits" : [
          {
            "_index" : "so_test18",
            "_type" : "_doc",
            "_id" : "o1JryGsB4TH56W1hhzGT",
            "_score" : 0.3971361,
            "_source" : {
              "id" : 1,
              "name" : "first second"
            }
          }
        ]
      }
    }
    

    在Elasticsearch 7.1.0中,您似乎可以使用
    关键字
    分析器,即使不创建特殊映射。至少我没有,下面的查询满足了我的需要:

    curl -H 'Content-Type: application/json' -iX POST 'http://localhost:9200/test/_search' -d '{
      "query": {
        "query_string": {
          "query": "first second",
          "analyzer": "keyword"
        }
      }
    }'
    

    谢谢你@JBone。但是如果我不控制映射,并且我不知道文档中将存在的确切字段,该怎么办?在这种情况下,有没有一种方法可以使用“精确匹配”进行搜索?似乎在不知道
    映射的情况下,我想这很难,但是如果您想尝试我答案中的第二种解决方案,请尝试。这里的内容是在
    映射
    中,对于
    名称
    字段,我需要添加
    fielddata=true
    ,脚本才能工作。谁知道你的<代码>映射< /代码>可能已经考虑<代码>字段数据=true< /Cord>,所以你可以试着运行第二个解决方案。通过
    你的url/index/\u映射
    向我们展示
    映射
    实际上,我很想找到一种不需要对映射进行任何操作的搜索方法。我还没有任何已知的映射,这就像一个研发任务,所以还没有什么可以展示的,唉,太好了。在新版本的Elastic(7.2版)中,他们添加了
    match\u bool\u prefix
    ,这可能会解决您的问题(通过让analyzer处于查询级别而不是映射级别),我们可以尝试一下。我的机器上有6.7版本,所以我需要得到这个新的Elasticsearch。但是一定要通过这个链接来理解我在说什么。谢谢,我来看看