【问题标题】:ElasticSearch Analyzer on text field文本字段上的 ElasticSearch Analyzer
【发布时间】:2017-04-06 14:09:04
【问题描述】:

这是我在 elasticSearch 上的字段:

"keywordName": {
        "type": "text",
        "analyzer": "custom_stop"
      }

这是我的分析器:

"custom_stop": {
      "type":      "custom",
      "tokenizer": "standard",
      "filter": [
        "my_stop",
        "my_snow",
        "asciifolding"
      ]
    }

这是我的过滤器:

           "my_stop": {
              "type":       "stop",
              "stopwords":  "_french_"
          },
           "my_snow" : {
                "type" : "snowball",
                "language" : "French"
            }

这是我的文档我的索引(在我唯一的字段中:keywordName):

“canne a peche”、“canne”、“canne a peche telescopique”、“iphone 8”、“iphone 8 外壳”、“iphone 8 保护套”、“iphone 8 充电器”、“iphone 8 new”

当我搜索“canne”时,它给了我“canne”文档,这就是我想要的:

GET ads/_search
{
   "query": {
    "match": {
      "keywordName": {
        "query": "canne",
        "operator":  "and"
      }
    }
  },
  "size": 1
}

当我搜索“canne à pêche”时,它会给我“canne a peche”,这也可以。与“Cannes à Pêche”相同 -> “canne a peche” -> 好的。

这是棘手的部分:当我搜索“iphone 8”时,它给了我“iphone 8 cover”而不是“iphone 8”。如果我更改大小,我设置 5(因为它返回包含“iphone 8”的 5 个结果)。我看到“iphone 8”是得分的第四个结果。首先是“iphone 8 cover”,然后是“iphone 8 case”,然后是“iphone 8 new”,最后是“iphone 8”......

这是查询的结果:

{
  "took": 5,
  "timed_out": false,
  "_shards": {
    "total": 5,
    "successful": 5,
    "failed": 0
  },
  "hits": {
    "total": 5,
    "max_score": 1.4009607,
    "hits": [
      {
        "_index": "ads",
        "_type": "keyword",
        "_id": "iphone 8 cover",
        "_score": 1.4009607,
        "_source": {
          "keywordName": "iphone 8 cover"
        }
      },
      {
        "_index": "ads",
        "_type": "keyword",
        "_id": "iphone 8 case",
        "_score": 1.4009607,
        "_source": {
          "keywordName": "iphone 8 case"
        }
      },
      {
        "_index": "ads",
        "_type": "keyword",
        "_id": "iphone 8 new",
        "_score": 0.70293105,
        "_source": {
          "keywordName": "iphone 8 new"
        }
      },
      {
        "_index": "ads",
        "_type": "keyword",
        "_id": "iphone 8",
        "_score": 0.5804671,
        "_source": {
          "keywordName": "iphone 8"
        }
      },
      {
        "_index": "ads",
        "_type": "keyword",
        "_id": "iphone 8 charge",
        "_score": 0.46705723,
        "_source": {
          "keywordName": "iphone 8 charge"
        }
      }
    ]
  }
}

我怎样才能在关键字“canne a peche”(重音、大写字母、复数)方面保持灵活性,但还要告诉他如果有完全匹配(“iphone 8”=“iphone 8”),给我确切的关键字名称?

【问题讨论】:

    标签: elasticsearch similarity analyzer elasticsearch-analyzers


    【解决方案1】:

    我建议是这样的:

        "keywordName": {
          "type": "text",
          "analyzer": "custom_stop",
          "fields": {
            "raw": {
              "type": "keyword"
            }
          }
        }
    

    还有查询:

    {
      "query": {
        "bool": {
          "should": [
            {
              "match": {
                "keywordName": {
                  "query": "iphone 8",
                  "operator": "and"
                }
              }
            },
            {
              "term": {
                "keywordName.raw": {
                  "value": "iphone 8"
                }
              }
            }
          ]
        }
      },
      "size": 10
    }
    

    【讨论】:

    • 这是我一直在寻找的行为!谢谢
    • 是否可以提升“最接近匹配”的结果?我的意思是 -> 如果我搜索“sâmsung”,则有 1 个标记:“samsung”。但最好的分数是“三星银河”(1.11),然后是“三星充电器”(0.94)和“三星”(0.84)。我怎么能告诉它提升 "samsung" 因为它是最接近 "sâmsung" 的匹配项?而不是“三星银河”或“三星充电器”
    【解决方案2】:

    匹配查询使用 tf/idf 算法。这意味着您将获得按频率排序的模糊搜索结果。如果您想在完全匹配的情况下获得结果,您应该在之前创建一个 query_string 案例,如果没有结果,请使用您的匹配查询。

    【讨论】:

    • 所以我必须使用 2 个查询来满足我的期望?
    • 这就是我的看法。我也不明白为什么 iphone 8 是第 4 个结果。 tf/idf 应该给它最高的频率。
    • @Gun 你能用 size=5 显示你的搜索结果吗
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-22
    • 1970-01-01
    • 2021-10-15
    • 2021-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多