【问题标题】:Relative word match in elastic search弹性搜索中的相对词匹配
【发布时间】:2016-02-04 01:25:51
【问题描述】:

Elastic 搜索的新手,以下是我想要实现的目标,即与查询字符串相对匹配的任何内容都应返回结果

创建如下示例索引

curl -XPUT 'http://localhost:9200/prj1/mod/java' -d '{
    "project_name": "Java_SE"
}'

curl -XPUT 'http://localhost:9200/prj1/mod/java2Ed' -d '{
    "project_name": "Java 2 Edition"
}'

curl -XPUT 'http://localhost:9200/prj1/mod/javaee' -d '{
    "project_name": "Java_EE"
}'

搜索时

curl -XGET 'http://localhost:9200/prj1/mod/_search' -d '{"query" : {"match" : {"project_name" : "Java"}}}'

返回以下结果

{"took":6,"timed_out":false,"_shards":{"total":5,"successful":5,"failed":0},"hits":{"total":1,"max_score":0.15342641,"hits":[{"_index":"prj1","_type":"mod","_id":"java2Ed","_score":0.15342641,"_source":{
"project_name": "Java 2 Edition"
}}]}}

它不会返回名称为“Java_SE”、“Java 2 Edition”和“Java_EE”的所有项目。

需要使用匹配文本“示例”获取找到的所有内容 我的文本中也可能有这样的数据

这是一个示例代码 这个例子:11是好的 您正在寻找的示例不可用。

我在这里做错了什么。

【问题讨论】:

    标签: elasticsearch


    【解决方案1】:

    你需要使用edge ngram 过滤器来解决这个问题。使用以下设置创建索引

    PUT prj1
    {
      "settings": {
        "analysis": {
          "filter": {
            "ngram_filter": {
              "type": "edgeNGram",
              "min_gram": 2,
              "max_gram": 8
            }
          },
          "analyzer": {
            "relative": {
              "tokenizer": "standard",
              "filter": [
                "lowercase",
                "ngram_filter"
              ]
            }
          }
        }
      },
      "mappings": {
        "mod": {
          "properties": {
            "project_name": {
              "type": "string",
              "analyzer": "relative",
              "search_analyzer": "standard"
            }
          }
        }
      }
    }
    

    所以 java_se 将有令牌 ja、jav java 等,您的 match query 将起作用。

    感谢@sean,您需要将ngram filter 用于complete_java_book、my_java_applet 等字词。您可能需要考虑在_ 上破坏字词如果您正在使用_ 作为项目名称的命名约定,是吗?

    希望这会有所帮助。

    【讨论】:

    • 此解决方案不一定正确,尽管它适用于问题中给出的示例,但不适用于许多类似或可能的示例。例如,标题“the_complete_java_book”不会与使用您提供的映射的搜索“java”匹配。事实上,任何不以“java”开头的标题都不会匹配。
    • @sean,是的,您是对的,您必须为此使用 ngram。假设所有项目都使用下划线作为命名约定,那么在下划线上打断单词会更好。我会更新答案。感谢您指出。
    • 是的,这完全取决于您对标题字段内容的假设以及问题中不清楚的所需匹配行为:)
    • @ChintanShah25 ,我们不能使用 queryString 并像 java* 一样传递正则表达式吗?既然分析了项目名称,查询字符串应该可以处理它。
    • @Richa 是的,它会起作用,但不会匹配 complete_java_book,正如肖恩指出的那样。您将不得不使用*java*,这是不推荐的,因为它会扫描倒排索引中的每个标记。 OP 没有指定任何特定的模式来帮助我们提供更好的解决方案
    【解决方案2】:

    这是因为默认情况下,elasticsearch 将使用standard tokenizer,它不会在下划线“_”字符上分割文本。因此,当您执行搜索时,您正在搜索只有文档 java2ED 具有标记的“java”标记。

    【讨论】:

      【解决方案3】:

      您也可以使用query_string。

      curl -XGET 'http://localhost:9200/prj1/mod/_search' -d '{"query" : {"query_string" : {"project_name" : "*Java*"}}}'
      

      【讨论】:

        猜你喜欢
        • 2015-08-02
        • 1970-01-01
        • 1970-01-01
        • 2021-09-12
        • 2015-03-12
        • 2017-01-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多