我在elasticsearch
中有文档,其中包含.
,即full stop
作为标题中的单词分隔符。
例如title
The.Handmaids.Tale.S02E05.WEBRip.x264-TBS[ettv]
因此,如果我搜索"The Handmaids Tale S02E05 WEBRip"
我的elasticsearch
查询成为
$params['body']['query']['bool']['must'][]['match']['title'] = The
$params['body']['query']['bool']['must'][]['match']['title'] = Handmaids
$params['body']['query']['bool']['must'][]['match']['title'] = Tale
$params['body']['query']['bool']['must'][]['match']['title'] = S02E05
$params['body']['query']['bool']['must'][]['match']['title'] = WEBRip
此查询不会返回上述文档。
所以我如何使elasticsearch
忽略。 aka标题中的句号,然后在我搜索“ The Handmaids Tale S02E05 WEBRip”时返回该文档?
我正在使用最新的Elasticsearch 6.3
我当前的index mapping
是
"mappings": {
"content": {
"properties": {
"title":{
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
},
"tags": { "type": "text" },
"category": { "type": "short" },
"sub_category": { "type": "short" },
"size": { "type": "long" },
"uploaders": { "type": "integer" },
"downloaders": { "type": "integer" },
"upload_date": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"uploader":{
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
}
}
}
}
update1:来自此https://stackoverflow.com/a/40136928/1642018
我想到了这个
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"type": "custom",
"tokenizer": "standard",
"char_filter": [
"replace_dot"
]
}
},
"char_filter": {
"replace_dot": {
"type": "pattern_replace",
"pattern": "\\.",
"replacement": " "
}
}
}
},
以及类似的映射
"title":{
"type": "text",
"analyzer": "my_analyzer",
"fields": {
"raw": {
"type": "keyword"
}
}
},
我创建了一个新索引,但仍然没有运气
我用"title": {"type":"string", "analyzer":"my_analyzer"}
定义了映射-但无济于事。
如果我针对新的分析器在新索引上调用localhost:9200/_analyze
,则该字符串将被完美分解。
例如
curl -X POST "localhost:9200/newindex3/_analyze?pretty" -H 'Content-Type: application/json' -d'
{
"analyzer": "my_analyzer",
"text": "John.Doe.mill.dane"
}
'
{
"tokens" : [
{
"token" : "John",
"start_offset" : 0,
"end_offset" : 4,
"type" : "<ALPHANUM>",
"position" : 0
},
{
"token" : "Doe",
"start_offset" : 5,
"end_offset" : 8,
"type" : "<ALPHANUM>",
"position" : 1
},
{
"token" : "mill",
"start_offset" : 9,
"end_offset" : 13,
"type" : "<ALPHANUM>",
"position" : 2
},
{
"token" : "dane",
"start_offset" : 14,
"end_offset" : 18,
"type" : "<ALPHANUM>",
"position" : 3
}
]
}
但是搜索仍然没有返回预期的文档。
我想念什么?
update2:现在,我正要在插入索引之前通过使用
'title' => str_replace('.', ' ', $results[$i]['title'])
答案 0 :(得分:0)
您首先需要了解分析器在Elasticsearch中的工作方式。
由于您在字段标题的映射中未提及任何分析器,因此将使用标准分析器。
现在,您需要查看标准分析器如何根据您的文本生成令牌,即它如何存储令牌以进行搜索
这是您发短信的一个例子
GET _analyze
{
"text": ["The.Handmaids.Tale.S02E05.WEBRip.x264-TBS[ettv]"],
"analyzer": "standard"
}
下面是结果
{
"tokens": [
{
"token": "the.handmaids.tale.s02e05",
"start_offset": 0,
"end_offset": 25,
"type": "<ALPHANUM>",
"position": 0
},
{
"token": "webrip.x264",
"start_offset": 26,
"end_offset": 37,
"type": "<ALPHANUM>",
"position": 1
},
{
"token": "tbs",
"start_offset": 38,
"end_offset": 41,
"type": "<ALPHANUM>",
"position": 2
},
{
"token": "ettv",
"start_offset": 42,
"end_offset": 46,
"type": "<ALPHANUM>",
"position": 3
}
]
}
这是您的查询无法工作的原因,因为它可以对令牌进行完全匹配。
您需要做的是制作一个如下所示的自定义分析器
PUT test_pattern
{
"settings": {
"number_of_shards": 1,
"analysis": {
"analyzer": {
"my_analyzer": {
"type": "pattern",
"pattern": "\\."
}
}
}
}
}
并将映射中的分析器更改为 my_analyzer
"mappings": {
"content": {
"properties": {
"title": {
"type": "text",
"analyzer":"my_analyzer",
"fields": {
"raw": {
"type": "keyword"
}
}
},
"tags": {
"type": "text"
},
"category": {
"type": "short"
},
"sub_category": {
"type": "short"
},
"size": {
"type": "long"
},
"uploaders": {
"type": "integer"
},
"downloaders": {
"type": "integer"
},
"upload_date": {
"type": "date",
"format": "yyyy-MM-dd HH:mm:ss"
},
"uploader": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
}
}
}
}
}
}