如何解释用户搜索查询(在Elasticsearch中)

时间:2019-02-27 12:33:57

标签: amazon-web-services elasticsearch nlp full-text-search interpretation

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

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

我想解释一下:

类别过滤条件是“床”和“孩子” 滤色片为红色 尺寸过滤器为120厘米

是否有准备好进行Elasticsearch的工具? 在Elasticsearch之前需要NLP吗?

1 个答案:

答案 0 :(得分:0)

Elasticsearch本身非常强大,并且只要对数据进行了充分的索引和查询,就能够将最相关的结果返回给全文搜索查询。

在幕后,对于全文搜索(对于text analysis类型的字段),它始终执行texttext analyzer由字符过滤器,令牌生成器和令牌过滤器组成。

例如,synonym token filter可以在用户查询中将kids替换为children

上面,现代网站上的搜索查询通常是通过用户界面中的类别选择器来实现的,可以通过查询Elasticsearch的{​​{3}}字段来轻松实现。

正确地对数据建模并调整索引以实现所需的搜索可能就足够了;如果这还不够的话,您总是可以在客户端添加一些类似于NLP的逻辑层,例如@ 2ps建议。

现在让我展示一个玩具示例,说明如何使用keyword令牌过滤器和synonym功能。

让我们定义映射

假设我们的产品具有以下属性: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"
                        ]
                    }
                }
            }
        }
    }
}

请注意,我们为字段keywordCategory选择了类型Color

现在,这些copy_tosynonym呢?

copy_to会做什么?

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

synonym会做什么?

要启用copy_to,我们需要定义一个自定义分析器,请参阅我们在上文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我们将能够对其进行查询。

让我们看看。

执行搜索!

现在,我们可以通过简单的synonym查询来尝试索引:

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如何解释用户的查询?

通过query_string很容易做到:

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
    }
  ]
}

如您所见,没有令牌kids,但是有令牌children

另一方面,在此示例中,Elasticsearch无法解析床的大小:令牌120cm与任何东西都不匹配,因为所有大小都是整数,例如{{1 }},120等。需要进行另一层调整才能从150令牌中提取120


我希望这能使您了解使用Elasticsearch的内置文本分析功能可以实现的目标!