【问题标题】:Elastic Search Exact Match - wrong results弹性搜索完全匹配 - 错误的结果
【发布时间】:2019-01-01 20:44:52
【问题描述】:

我已经根据教程和 ElasticSearch 站点的官方文档进行了以下两次搜索,但我得到的结果更像是包含结果,而不是完全匹配。 我对 ES 很陌生,所以请原谅任何菜鸟的错误。 任何帮助,将不胜感激。

根据我到目前为止所经历的教程,他们的结果并非如此。所以我很困惑为什么我会得到我现在的结果。

数据结构:

{
    "_scroll_id": "cXVlcnlBbmRGZXRjaDsxOzI3OlRsWmVmMGh5VENLR0FVclB3eXpIaVE7MDs=",
    "took": 7,
    "timed_out": false,
    "_shards": {
        "total": 1,
        "successful": 1,
        "failed": 0
    },
    "hits": {
        "total": 16896,
        "max_score": 1,
        "hits": [
            {
                "_index": "cus_index",
                "_type": "place",
                "_id": "71272349",
                "_score": 1,
                "_source": {
                    "id": 34543,
                    "date1": "1928-09-13 00:00:00",
                    "date2": "1929-01-01 00:00:00",
                    "code": "1000",
                    "phrase": "GOD MODE",
                    "boolCol": false
                }
            },
            {
                "_index": "cus_index",
                "_type": "place",
                "_id": "71272349",
                "_score": 1,
                "_source": {
                    "id": 78635,
                    "date1": "1928-09-13 00:00:00",
                    "date2": "1929-01-01 00:00:00",
                    "code": "3000",
                    "phrase": "THANK GOD",
                    "boolCol": false
                }
            },
            {
                "_index": "cus_index",
                "_type": "place",
                "_id": "71272349",
                "_score": 1,
                "_source": {
                    "id": 45645,
                    "date1": "1928-09-13 00:00:00",
                    "date2": "1929-01-01 00:00:00",
                    "code": "5000",
                    "phrase": "SOME OTHER GOD PHRASE",
                    "boolCol": false
                }
            },
        ]
    }
}

查询:

// returns all rows
{
    "query" : {
        "constant_score" : {
            "filter" : {
                "match" : {
                    "phrase": "GOD MODE"
                }
            }
        }
    }
}

// this returns all rows
{
    "query" : {
        "query_string": {
            "query": "GOD MODE",
            "fields": ["phrase"]
        }
    }
}

// this returns no rows
{
    "query" : {
        "term": {
            "phrase": "GOD MODE"
        }
    }
}

映射:

{
    "cus_index": {
        "aliases": {},
        "mappings": {
            "place": {
                "properties": {
                    "id": {
                        "type": "int"
                    },
                    "date1": {
                        "type": "date"
                    },
                    "date2": {
                        "type": "date"
                    },
                    "code": {
                        "type": "string"
                    },
                    // this is the important one
                    // i just guessed the others as this is an example, But the col in qu is a string
                    "phrase": {
                        "type": "string"
                    },
                    "boolCol": {
                        "type": "boolean"
                    }
                }
            }
        },
        "settings": {
            "index": {
                "creation_date": "1545321229864",
                "number_of_shards": "1",
                "number_of_replicas": "0",
                "uuid": "4PpzZ49SQZWDDW8sawOIaA",
                "version": {
                    "created": "2030199"
                }
            }
        },
        "warmers": {}
    }
}

ES 版本:

{
    "name": "Test Node",
    "cluster_name": "firsttestnode",
    "version": {
        // this was a very old version latest "6.5.4" this is what i 
        // should have been using for the answers below to work.
        "number": "2.3.1",
        "build_hash": "bd980929010aef404e7cb0843e61d0665269fc39",
        "build_timestamp": "2016-04-04T12:25:05Z",
        "build_snapshot": false,
        "lucene_version": "5.5.0"
    },
    "tagline": "Test tag line"
}

---------- 回答尝试 ------------------------ ------------

我 PUT 和 POST 到下面给定的 Url 的以下正文并收到以下错误:

// URL: http://ip_address:9200/test_index1

{
  "mappings": {
    "demo":{
       "properties": {
          "phrase": {
            "type": "string"
          },
          "phrase1": {
            "type": "keyword"
          }
       }
    }
  }
}

// errors
{
    "error": {
        "root_cause": [
            {
                "type": "mapper_parsing_exception",
                "reason": "No handler for type [keyword] declared on field [phrase1]"
            }
        ],
        "type": "mapper_parsing_exception",
        "reason": "Failed to parse mapping [demo]: No handler for type [keyword] declared on field [phrase1]",
        "caused_by": {
            "type": "mapper_parsing_exception",
            "reason": "No handler for type [keyword] declared on field [phrase1]"
        }
    },
    "status": 400
}

以下两个答案都按预期工作。 感谢双方。不太确定回答是否正确,但对于其他阅读,我会推荐两者。

只有答案 1 中的 '"type": "string"' 应该是 '"type": "text"' 才能使示例正常工作。

【问题讨论】:

  • 还将您的索引映射添加到问题中。
  • 抱歉,我不确定如何添加映射。这是我第一次使用 ES
  • 我的错。在 Kibana 中给 - GET /your_index_name 将为您提供 JSON 格式的映射
  • 我已更新我的问题以显示映射
  • @TheMan68- 你的 ES 版本是什么

标签: elasticsearch search


【解决方案1】:

我建议将短语属性更新如下:

"phrase": {
   "type": "text",
   "fields": {
      "keyword": {
         "type": "keyword"
      }
   }
}

在上述情况下,当索引文档时,您只需将值传递给phrase 字段,phrase.keyword 就会自动索引。

当您想要进行完全匹配时,您可以使用以下术语查询:

{
   "term": {
      "phrase.keyword": "some text"
   }
}

【讨论】:

  • 你好。这似乎没有按预期工作。我不认为您可以编写一个如何创建索引的最小示例,如下所示 url/anIndex/entry 列正文感谢您的帮助
  • 我选择了这个结构作为答案,因为我也会推荐短语.keyword 结构。但是“类型”:“字符串”必须更改为“类型”:“文本”才能为我工作
  • 是的,它应该是 text 而不是 string。感谢您指出。我更正了我的答案。
  • 非常感谢朋友。你和下面的答案都很难选择。你们俩都帮了大忙
【解决方案2】:

term 查询查找包含倒排索引中指定的确切术语的文档。

TL;DR:

例子:

PUT test_index1
{
  "mappings": {
    "demo":{
       "properties": {
          "phrase": {
            "type": "string"
          },
          "phrase1": {
            "type": "keyword"
          }
       }
    }
  }
}


POST test_index1/demo/1
{
  "phrase":"GOOD GOD",
  "phrase1":"GOOD GOD"
}

GET  test_index1/_search
{
  "query": {
    "match": {
      "phrase": "GOOD"
    }
  }
}

以上返回结果

GET  test_index1/_search
{
  "query": {
    "term": {
      "phrase1": "GOOD"
    }
  }
}

以上不返回结果

你甚至可以使用_analyze

GET  test_index1/_analyze
{
  "field": "phrase",
  "text": ["GOOD GOD"]
}

查看文档是如何存储在倒排索引中的。

回答您的问题:

词条查询查找exact match。由于您的词组类型是字符串,GOD MODE 一词存储为 GOD 和 MODE,其中词条查询将与 GOD MODE 完全匹配。您必须将其更改为 Keyword 或使用 match 查询

【讨论】:

  • 什么是倒排索引?
  • @TheMan68 - 这是一个用于存储文档的索引概念
  • 您好。非常感谢。关于为什么我得到这些结果,那是一个非常有用的过程。我的下一个问题词是我需要能够在“phrase = val ORphrase = val2 ORphrase = val3”上匹配这些花括号,确切地说还必须与通配符搜索兼容。那么存储它们的最佳方式是什么?如果我将它们存储为关键字,这可能吗?而且我已经尝试过匹配短语,它仍然给了我所有的结果
  • 我会说你可以使用字段类型来存储精确和文本来存储索引文档。
  • 当我使用您推荐的内容发布帖子时出现的错误,请查看答案
猜你喜欢
  • 1970-01-01
  • 2020-03-10
  • 1970-01-01
  • 1970-01-01
  • 2019-02-01
  • 2014-08-23
  • 1970-01-01
  • 1970-01-01
  • 2017-10-01
相关资源
最近更新 更多