0

当我的访问者使用我们的搜索功能时,我想为他们提供最好的结果。为此,我想解释搜索查询。

例如,用户搜索“120 厘米儿童的红色床”

我想将其解释如下:

类别过滤器是“床”和“儿童”颜色过滤器是红色尺寸过滤器是 120 厘米

是否有适用于 Elasticsearch 的工具?在 Elasticsearch 之前我需要 NLP 吗?

4

1 回答 1

0

Elasticsearch 本身非常强大,并且非常有能力将最相关的结果返回到全文搜索查询,前提是数据被充分索引和查询。

在后台,它总是为全文搜索执行文本分析text(对于 type 的字段)。文本分析器由字符过滤器、标记器和标记过滤器组成。

例如,同义词标记过滤器可以在用户查询中替换kids为。children

除此之外,现代网站上的搜索查询通常通过 UI 中的类别选择器来实现,这可以通过keywordElasticsearch 的查询字段轻松实现。

正确建模数据并调整其索引以实现您需要的搜索可能就足够了 - 如果这还不够,您可以随时在客户端添加一些额外的类似 NLP 的逻辑层,就像 @2ps 建议的那样。

现在让我展示一个玩具示例,说明您可以使用synonym令牌过滤器和copy_to功能实现什么。

让我们定义映射

假设我们的产品具有以下属性:CategoryColorSize.LengthCM

映射将类似于:

PUT /my_index
{
    "mappings": {
        "properties": {
            "Category": {
                "type": "keyword",
                "copy_to": "DescriptionAuto"
            },
            "Color": {
                "type": "keyword",
                "copy_to": "DescriptionAuto"
            },
            "Size": {
                "properties": {
                    "LengthCM": {
                        "type": "integer",
                        "copy_to": "DescriptionAuto"
                    }
                }
            },
            "DescriptionAuto": {
                "type": "text",
                "analyzer": "MySynonymAnalyzer"
            }
        }
    },
    "settings": {
        "index": {
            "analysis": {
                "analyzer": {
                    "MySynonymAnalyzer": {
                        "tokenizer": "standard",
                        "filter": [
                            "MySynonymFilter"
                        ]
                    }
                },
                "filter": {
                    "MySynonymFilter": {
                        "type": "synonym",
                        "lenient": true,
                        "synonyms": [
                            "kid, kids => children"
                        ]
                    }
                }
            }
        }
    }
}

请注意,我们keyword为字段Category和选择了类型Color

现在,这些copy_tosynonym呢?

copy_to做什么?

每次我们发送一个索引对象到我们的索引中,关键字字段的值Category将被复制到一个全文字段中DescritpionAuto。这就是这样copy_to做的。

synonym做什么?

要启用synonym我们需要定义一个自定义分析器,请参阅MySynonymAnalyzer我们在"settings"上面定义的。

粗略地说,它将用=>右侧的标记替换与左侧匹配的每个标记。

文件会是什么样子?

让我们插入一些示例文档:

POST /my_index/_doc
{
    "Category": [
        "beds",
        "adult"
    ],
    "Color": "red",
    "Size": {
        "LengthCM": 150
    }
}

POST /my_index/_doc
{
    "Category": [
        "beds",
        "children"
    ],
    "Color": "red",
    "Size": {
        "LengthCM": 120
    }
}

POST /my_index/_doc
{
    "Category": [
        "couches",
        "adult",
        "family"
    ],
    "Color": "blue",
    "Size": {
        "LengthCM": 200
    }
}

POST /my_index/_doc
{
    "Category": [
        "couches",
        "adult",
        "family"
    ],
    "Color": "red",
    "Size": {
        "LengthCM": 200
    }
}

如您所见,DescriptionAuto原始文档中不存在 - 尽管copy_to我们将能够查询它。

让我们看看如何。

执行搜索!

query_string现在我们可以通过一个简单的查询来尝试我们的索引:

POST /my_index/_doc/_search
{
    "query": {
        "query_string": {
            "query": "red beds for kids 120cm",
            "default_field": "DescriptionAuto"
        }
    }
}

结果将如下所示:

  "hits": {
    ...
    "max_score": 2.3611186,
    "hits": [
      {
        ...
        "_score": 2.3611186,
        "_source": {
          "Category": [
            "beds",
            "children"
          ],
          "Color": "red",
          "Size": {
            "LengthCM": 120
          }
        }
      },
      {
        ...
        "_score": 1.0998137,
        "_source": {
          "Category": [
            "beds",
            "adult"
          ],
          "Color": "red",
          "Size": {
            "LengthCM": 150
          }
        }
      },
      {
        ...
        "_score": 0.34116736,
        "_source": {
          "Category": [
            "couches",
            "adult",
            "family"
          ],
          "Color": "red",
          "Size": {
            "LengthCM": 200
          }
        }
      }
    ]
  }

带有类别bedschildren颜色的文档red位于顶部。而且它的相关性得分是其后续的两倍!

如何检查 Elasticsearch 如何解释用户的查询?

通过分析 API很容易做到:

POST /my_index/_analyze
{
    "text": "red bed for kids 120cm",
    "analyzer": "MySynonymAnalyzer"
}

{
  "tokens": [
    {
      "token": "red",
      "start_offset": 0,
      "end_offset": 3,
      "type": "<ALPHANUM>",
      "position": 0
    },
    {
      "token": "bed",
      "start_offset": 4,
      "end_offset": 7,
      "type": "<ALPHANUM>",
      "position": 1
    },
    {
      "token": "for",
      "start_offset": 8,
      "end_offset": 11,
      "type": "<ALPHANUM>",
      "position": 2
    },
    {
      "token": "children",
      "start_offset": 12,
      "end_offset": 16,
      "type": "SYNONYM",
      "position": 3
    },
    {
      "token": "120cm",
      "start_offset": 17,
      "end_offset": 22,
      "type": "<ALPHANUM>",
      "position": 4
    }
  ]
}

如您所见,没有 token kids,但有 token children

附带说明一下,在此示例中,Elasticsearch 无法解析床的大小:token120cm不匹配任何内容,因为所有大小都是整数,例如120,150等。需要进行另一层调整120120cm令牌中提取。


我希望这可以让您了解 Elasticsearch 的内置文本分析功能可以实现什么!

于 2020-02-28T19:13:22.530 回答