当访问者使用我们的搜索功能时,我希望为他们提供最好的结果。 为此,我想解释一下搜索查询:
例如,某个用户搜索“ 120厘米儿童红色床”
我想解释一下:
类别过滤条件是“床”和“孩子” 滤色片为红色 尺寸过滤器为120厘米
是否有准备好进行Elasticsearch的工具? 在Elasticsearch之前需要NLP吗?
答案 0 :(得分:0)
Elasticsearch本身非常强大,并且只要对数据进行了充分的索引和查询,就能够将最相关的结果返回给全文搜索查询。
在幕后,对于全文搜索(对于text analysis类型的字段),它始终执行text
。 text analyzer由字符过滤器,令牌生成器和令牌过滤器组成。
例如,synonym token filter可以在用户查询中将kids
替换为children
。
上面,现代网站上的搜索查询通常是通过用户界面中的类别选择器来实现的,可以通过查询Elasticsearch的{{3}}字段来轻松实现。
正确地对数据建模并调整索引以实现所需的搜索可能就足够了;如果这还不够的话,您总是可以在客户端添加一些类似于NLP的逻辑层,例如@ 2ps建议。
现在让我展示一个玩具示例,说明如何使用keyword
令牌过滤器和synonym
功能。
假设我们的产品具有以下属性:Category
,Color
和Size.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_to
和synonym
呢?
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
}
}
}
]
}
顶部为类别beds
和children
,颜色为red
的文档。其相关性得分是其后续活动的两倍!
通过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的内置文本分析功能可以实现的目标!