【问题标题】:Not able to search for string within a string in elasticsearch index无法在弹性搜索索引中的字符串中搜索字符串
【发布时间】:2012-12-07 09:40:10
【问题描述】:

我正在尝试为我的 elasticsearch 实例设置全名匹配和部分名称匹配的映射:

curl -XPUT 'http://127.0.0.1:9200/test/?pretty=1'  -d '{
  "mappings": {
    "venue": {
      "properties": {
        "location": {
          "type": "geo_point"
        },
        "name": {
          "fields": {
            "name": {
              "type": "string",
              "analyzer": "full_name"
            },
            "partial": {
              "search_analyzer": "full_name",
              "index_analyzer": "partial_name",
              "type": "string"
            }
          },
          "type": "multi_field"
        }
      }
    }
  },
  "settings": {
    "analysis": {
      "filter": {
        "swedish_snow": {
          "type": "snowball",
          "language": "Swedish"
        },
        "name_synonyms": {
          "type": "synonym",
          "synonyms_path": "name_synonyms.txt"
        },
        "name_ngrams": {
          "side": "front",
          "min_gram": 2,
          "max_gram": 50,
          "type": "edgeNGram"
        }
      },
      "analyzer": {
        "full_name": {
          "filter": [
            "standard",
            "lowercase"
          ],
          "type": "custom",
          "tokenizer": "standard"
        },
        "partial_name": {
          "filter": [
            "swedish_snow",
            "lowercase",
            "name_synonyms",
            "name_ngrams",
            "standard"
          ],
          "type": "custom",
          "tokenizer": "standard"
        }
      }
    }
  }
}'

我用一些数据填充它:

curl -XPOST 'http://127.0.0.1:9200/_bulk?pretty=1'  -d '
{"index" : {"_index" : "test", "_type" : "venue"}}
{"location" : [59.3366, 18.0315], "name" : "johnssons"}
{"index" : {"_index" : "test", "_type" : "venue"}}
{"location" : [59.3366, 18.0315], "name" : "johnsson"}
{"index" : {"_index" : "test", "_type" : "venue"}}
{"location" : [59.3366, 18.0315], "name" : "jöhnsson"}
'

执行一些搜索来测试, 全名:

curl -XGET 'http://127.0.0.1:9200/test/venue/_search?pretty=1' -d '{
  "query": {
    "bool": {
      "should": [
        {
          "text": {
            "name": {
              "boost": 1,
              "query": "johnsson"
            }
          }
        },
        {
          "text": {
            "name.partial": "johnsson"
          }
        }
      ]
    }
  }
}'

结果:

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 0.29834434,
    "hits": [
      {
        "_index": "test",
        "_type": "venue",
        "_id": "CAO-dDr2TFOuCM4pFfNDSw",
        "_score": 0.29834434,
        "_source": {
          "location": [
            59.3366,
            18.0315
          ],
          "name": "johnsson"
        }
      },
      {
        "_index": "test",
        "_type": "venue",
        "_id": "UQWGn8L9Squ5RYDMd4jqKA",
        "_score": 0.14663845,
        "_source": {
          "location": [
            59.3366,
            18.0315
          ],
          "name": "johnssons"
        }
      }
    ]
  }
}

部分名称:

curl -XGET 'http://127.0.0.1:9200/test/venue/_search?pretty=1' -d '{
  "query": {
    "bool": {
      "should": [
        {
          "text": {
            "name": {
              "boost": 1,
              "query": "johns"
            }
          }
        },
        {
          "text": {
            "name.partial": "johns"
          }
        }
      ]
    }
  }
}'

结果:

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 2,
    "max_score": 0.14663845,
    "hits": [
      {
        "_index": "test",
        "_type": "venue",
        "_id": "UQWGn8L9Squ5RYDMd4jqKA",
        "_score": 0.14663845,
        "_source": {
          "location": [
            59.3366,
            18.0315
          ],
          "name": "johnssons"
        }
      },
      {
        "_index": "test",
        "_type": "venue",
        "_id": "CAO-dDr2TFOuCM4pFfNDSw",
        "_score": 0.016878016,
        "_source": {
          "location": [
            59.3366,
            18.0315
          ],
          "name": "johnsson"
        }
      }
    ]
  }
}

名字中的名字:

curl -XGET 'http://127.0.0.1:9200/test/venue/_search?pretty=1' -d '{
  "query": {
    "bool": {
      "should": [
        {
          "text": {
            "ame": {
              "boost": 1,
              "query": "johnssons"
            }
          }
        },
        {
          "text": {
            "name.partial": "johnssons"
          }
        }
      ]
    }
  }
}'

结果:

{
  "took": 2,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 1,
    "max_score": 0.39103588,
    "hits": [
      {
        "_index": "test",
        "_type": "venue",
        "_id": "UQWGn8L9Squ5RYDMd4jqKA",
        "_score": 0.39103588,
        "_source": {
          "location": [
            59.3366,
            18.0315
          ],
          "name": "johnssons"
        }
      }
    ]
  }
}

如您所见,我只获得了一个场地,即johnssons。我不应该同时得到johnssons 和johnsson 吗?我在设置中做错了什么?

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    您正在使用 full_name 分析作为 name.partial 字段的搜索分析器。因此,您的查询被翻译成对术语 johnssons 的查询,它不匹配任何内容。

    您可以使用Analyze API 查看您的记录是如何编入索引的。比如这个命令

    curl -XGET 'http://127.0.0.1:9200/test/_analyze?analyzer=partial_name&pretty=1' -d 'johnssons'
    

    会告诉你,在索引期间,字符串“johnssons”被翻译成以下术语:“jo”、“joh”、“john”、“johns”、“johnss”、“johnsso”、“johnsson”。虽然这个命令

     curl -XGET 'http://127.0.0.1:9200/test/_analyze?analyzer=full_name&pretty=1' -d 'johnssons'
    

    会告诉你,在搜索过程中,字符串“johnssons”被翻译成术语“johnssons”。如您所见,您的搜索词与此处的数据不匹配。

    【讨论】:

    • 感谢您的回答。所以我想要得到一个更模糊的结果,必须使用 partial_name 作为 search_analyzer。但这会导致搜索结果不太精确......在这种情况下我应该怎么想。也许指定一个具有更高 min_gram 的新 front edgeNGram 分析器并提升它..?你会怎么做?
    • 这是典型的精确率与召回率折衷方案。在不了解所有用例以及想要支持的“部分匹配”类型的情况下,很难提出建议。我个人的偏好是使用一种分析器,将相同或相似名称的不同变体转换为单个术语(例如用于语音过滤器的雪球),并且如果无法使用专门的拼写检查器在搜索引擎之外处理拼写错误。
    • 嗯,好的。我可能会就此写另一个问题 =) 谢谢您的宝贵时间!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-12-07
    • 2021-06-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多