gpt4 book ai didi

elasticsearch - 定制分析器,用例:邮政编码[ElasticSearch]

转载 作者:行者123 更新时间:2023-12-02 22:56:38 29 4
gpt4 key购买 nike

将其设置为名为customers / customer的索引/类型。
此集合的每个文档都有一个邮政编码属性。
邮政编码基本上可以像这样:

  • 字符串-字符串(例如:8907-1009)
  • 字符串字符串(例如:211-20)
  • 字符串(例如:30200)

  • 我想将索引分析器设置为获取尽可能多的匹配文档。目前,我这样工作:
    PUT /customers/
    {
    "mappings":{
    "customer":{
    "properties":{
    "zip-code": {
    "type":"string"
    "index":"not_analyzed"
    }
    some string properties ...
    }
    }
    }

    当我搜索文档时,我正在使用该请求:
    GET /customers/customer/_search
    {
    "query":{
    "prefix":{
    "zip-code":"211-20"
    }
    }
    }

    如果您想进行严格的搜索,那就行得通。但是例如,如果邮政编码为“200 30”,则使用“200-30”进行搜索将不会给出任何结果。
    我想给我的索引分析器下订单,以解决这个问题。
    有人能帮我吗 ?
    谢谢。

    附言如果您需要更多信息,请让我知道;)

    最佳答案

    一旦您要查找变体,就不想使用not_analyzed

    让我们尝试使用其他映射:

    PUT zip
    {
    "settings": {
    "number_of_shards": 1,
    "analysis": {
    "analyzer": {
    "zip_code": {
    "tokenizer": "standard",
    "filter": [ ]
    }
    }
    }
    },
    "mappings": {
    "_doc": {
    "properties": {
    "zip": {
    "type": "text",
    "analyzer": "zip_code"
    }
    }
    }
    }
    }

    我们正在使用标准的分词器;字符串将在空白处和标点符号(包括破折号)处分解为标记。如果运行以下查询,则可以看到实际的 token :
    POST zip/_analyze
    {
    "analyzer": "zip_code",
    "text": ["8907-1009", "211-20", "30200"]
    }

    添加您的示例:
    POST zip/_doc
    {
    "zip": "8907-1009"
    }
    POST zip/_doc
    {
    "zip": "211-20"
    }
    POST zip/_doc
    {
    "zip": "30200"
    }

    现在查询似乎可以正常工作:
    GET zip/_search
    {
    "query": {
    "match": {
    "zip": "211-20"
    }
    }
    }

    如果您仅搜索“211”,这也将起作用。但是,这可能太宽容了,因为它还会找到“20”,“20-211”,“211-10”,...

    您可能想要的是短语搜索,其中查询中的所有标记都必须位于字段中,并且顺序正确:
    GET zip/_search
    {
    "query": {
    "match_phrase": {
    "zip": "211"
    }
    }
    }

    添加:

    如果邮政编码具有层次结构含义(如果您具有“211-20”,则希望在搜索“211”时找到它,但在搜索“20”时找不到),则可以使用 path_hierarchy tokenizer

    因此,将映射更改为此:
    PUT zip
    {
    "settings": {
    "number_of_shards": 1,
    "analysis": {
    "analyzer": {
    "zip_code": {
    "tokenizer": "zip_tokenizer",
    "filter": [ ]
    }
    },
    "tokenizer": {
    "zip_tokenizer": {
    "type": "path_hierarchy",
    "delimiter": "-"
    }
    }
    }
    },
    "mappings": {
    "_doc": {
    "properties": {
    "zip": {
    "type": "text",
    "analyzer": "zip_code"
    }
    }
    }
    }
    }

    使用上面相同的3个文档,您现在可以使用 match查询:
    GET zip/_search
    {
    "query": {
    "match": {
    "zip": "1009"
    }
    }
    }

    “1009”什么都找不到,但是“8907”或“8907-1009”会找到。

    如果您还想找到“1009”,但得分较低,则必须分析我显示的两种变体的邮政编码(结合映射的2个版本):
    PUT zip
    {
    "settings": {
    "number_of_shards": 1,
    "analysis": {
    "analyzer": {
    "zip_hierarchical": {
    "tokenizer": "zip_tokenizer",
    "filter": [ ]
    },
    "zip_standard": {
    "tokenizer": "standard",
    "filter": [ ]
    }
    },
    "tokenizer": {
    "zip_tokenizer": {
    "type": "path_hierarchy",
    "delimiter": "-"
    }
    }
    }
    },
    "mappings": {
    "_doc": {
    "properties": {
    "zip": {
    "type": "text",
    "analyzer": "zip_standard",
    "fields": {
    "hierarchical": {
    "type": "text",
    "analyzer": "zip_hierarchical"
    }
    }
    }
    }
    }
    }
    }

    以相反的顺序添加文档以正确测试它:
    POST zip/_doc
    {
    "zip": "1009-111"
    }

    然后搜索两个字段,但使用分层标记器将其增加3:
    GET zip/_search
    {
    "query": {
    "multi_match" : {
    "query" : "1009",
    "fields" : [ "zip", "zip.hierarchical^3" ]
    }
    }
    }

    然后您可以看到“1009-111”的得分比“8907-1009”的得分高得多。

    关于elasticsearch - 定制分析器,用例:邮政编码[ElasticSearch],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51709666/

    29 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com