【问题标题】:Productsearch with Elasticsearch使用 Elasticsearch 进行产品搜索
【发布时间】:2015-05-26 13:59:46
【问题描述】:

我对 elasticsearch 比较陌生,我想搜索具有品牌和类型名称的产品。 我已经尝试了一些,但我认为我缺少一些重要的东西来拥有一个可靠的搜索算法。这是我的方法:

产品看起来像这样:

{
  brandName: "Samsung",
  typeName: "PS-50Q7HX",
  ...
}

我将有一个输入字段。用户可以仅搜索品牌/类型或结合类型名称搜索品牌。例如

Samsung | Samsung PS-50Q7HX | PS-50Q7HX

为了消除 typeName 字段中的错误输入,我使用了一个 ngram 标记器,它在我只搜索类型时效果很好。但是结合brandName字段我遇到了麻烦。使用这样的东西效果不好(特别是当我也在品牌名称字段上使用 ngram 标记器时):

{
  "query" : {
    "multi_match" : {
      "query": "Samsung PS 50Q 7HX",
      "type": "cross_fields", 
      "fields": ["brandName", "typeName"]
    }
  }
}

当然我知道为什么这不适用于两个 ngram 标记器和一个混合字段,但我不知道如何以最好的方式解决这个问题。

我认为主要问题是我不知道用户是否输入了品牌名称,我考虑使用填充所有可用品牌的第二个索引,我用它来执行“预搜索”最终在我的查询字符串中给出了品牌名称。如果我找到匹配项,我可以将搜索字符串拆分为类型和品牌名称并执行更具体的搜索。喜欢这个

{
  "query": {
    "bool": {
      "must": [
        { "match": { "brandName": "Samsung" } },
        { "match": { "typeName": "PS-50Q7HX" } }
      ]
    }
  }
}

这听起来是个好方法吗?或者有没有人看到更好的方法?

感谢任何帮助!

非常感谢您的问候,

斯蒂芬

【问题讨论】:

  • “效果不好”是什么意思?你能否展示一些你得到的样本结果以及为什么它们不够好。看来您的品牌和类型具有非常不同的词汇结构,所以我很好奇您已经制作的内容会得到什么样的结果。
  • 感谢您的回答。当我对两个字段都使用 ngram 标记器并使用 multi_match 搜索时,例如“Samsung SGH”将是“Hama SGH-D500/Z300 Samsung ...”,但品牌完全错误,因为类型也与品牌匹配。

标签: elasticsearch


【解决方案1】:
  1. 为了消除用户的拼写错误,您使用了ngram 分析器,这是一个昂贵的分析器。您可以使用stem 分析器,它提供了一些灵活的选项来消除拼写错误

  2. 根据我的担心,您可以将其索引为单个字段,而不是在 2 个不同的字段中编制索引。

例如:- “FIELD_NAME”:“三星|PS-50Q7HX”

Brand nameProduct name 带有一些分隔符,我使用了 |。使用分隔符分析此字段值。所以你的内容数据将被索引如下

三星

PS-50Q7HX

然后您可以通过以下查询进行搜索

{
    "query": {
        "query-string": {
            "query": "Samsung PS-50Q7HX",
            "default_operator": "or",
            "fields": [
                "FIELD_NAME"
            ]
        }
    }
}

这将从索引中检索品牌名称为samsung 或产品名称为PS-50Q7Hx 的文档。您可以使用prefix 搜索,如果您使用default_operator 作为and,那么您的搜索将是最准确的。

【讨论】:

  • 嘿,非常感谢。这真的可以帮助我。但是我怎样才能消除产品类型中的打字错误呢?我的问题是网络上的类型通常非常不同,只有“大多数”部分是相同的。这就是为什么我想到了一个 ngram 标记器。 (例如,搜索 PS-50Q7HX 应该与搜索 PS-50Q7H/X 匹配相同的产品)Stem 仅适用于特定语言,对吗?
  • 是的,您是正确的stems 是特定于语言的。即使ngram 是一种代价高昂的方法,我们也可以将ngram 用于诸如极少更新请求之类的字段,并且其中没有更多的文字内容。
  • 但是如果你严格使用ngram 方法,那么就不需要遵循上述方法。因为上述方法仅适用于分隔符分析器意味着pattern 分析器。
  • 但是使用一个字段而不是两个字段似乎是一种好方法。我也不知道 default_operator 选项。这真的很有帮助elastic.co/guide/en/elasticsearch/reference/1.x/… 非常感谢!
  • default_operator 是一种逻辑运算符 AND、OR。这将在搜索字符串中执行
猜你喜欢
  • 2020-11-22
  • 1970-01-01
  • 1970-01-01
  • 2017-03-11
  • 1970-01-01
  • 1970-01-01
  • 2013-03-12
  • 2021-08-12
  • 2016-01-18
相关资源
最近更新 更多