Hüs*_*BAL 7 lucene search tokenize elasticsearch
我有一个索引,如下面的设置和映射;
{
"settings":{
"index":{
"analysis":{
"analyzer":{
"analyzer_keyword":{
"tokenizer":"keyword",
"filter":"lowercase"
}
}
}
}
},
"mappings":{
"product":{
"properties":{
"name":{
"analyzer":"analyzer_keyword",
"type":"string",
"index": "not_analyzed"
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我正在努力为name字段上的通配符搜索实现.我的示例数据是这样的;
[
{"name": "SVF-123"},
{"name": "SVF-234"}
]
Run Code Online (Sandbox Code Playgroud)
当我执行以下查询时;
http://localhost:9200/my_index/product/_search -d '
{
"query": {
"filtered" : {
"query" : {
"query_string" : {
"query": "*SVF-1*"
}
}
}
}
}'
Run Code Online (Sandbox Code Playgroud)
它返回SVF-123,SVF-234.我认为,它仍然是数据的标记.它必须只返回SVF-123.
你能帮忙吗?
提前致谢
Ale*_*vik 14
这里有一些问题.
首先,您说您不希望术语分析索引时间.然后,配置了一个分析器(用于搜索时间),生成不兼容的术语.(他们是小写的)
默认情况下,所有术语都_all使用标准分析器在-field中结束.那是你最终搜索的地方.由于它在" - "上标记,因此最终得到"*SVF"和"1*"的OR.
尝试在_all和name上做一个术语方面,看看发生了什么.
这是一个可运行的游戏和要点:https://www.found.no/play/gist/3e5fcb1b4c41cfc20226(https://gist.github.com/alexbrasetvik/3e5fcb1b4c41cfc20226)
您需要确保索引的术语与您搜索的内容兼容.你可能想要禁用_all,因为它可能会使正在发生的事情变得混乱.
#!/bin/bash
export ELASTICSEARCH_ENDPOINT="http://localhost:9200"
# Create indexes
curl -XPUT "$ELASTICSEARCH_ENDPOINT/play" -d '{
"settings": {
"analysis": {
"text": [
"SVF-123",
"SVF-234"
],
"analyzer": {
"analyzer_keyword": {
"type": "custom",
"tokenizer": "keyword",
"filter": [
"lowercase"
]
}
}
}
},
"mappings": {
"type": {
"properties": {
"name": {
"type": "string",
"index": "not_analyzed",
"analyzer": "analyzer_keyword"
}
}
}
}
}'
# Index documents
curl -XPOST "$ELASTICSEARCH_ENDPOINT/_bulk?refresh=true" -d '
{"index":{"_index":"play","_type":"type"}}
{"name":"SVF-123"}
{"index":{"_index":"play","_type":"type"}}
{"name":"SVF-234"}
'
# Do searches
# See all the generated terms.
curl -XPOST "$ELASTICSEARCH_ENDPOINT/_search?pretty" -d '
{
"facets": {
"name": {
"terms": {
"field": "name"
}
},
"_all": {
"terms": {
"field": "_all"
}
}
}
}
'
# Analyzed, so no match
curl -XPOST "$ELASTICSEARCH_ENDPOINT/_search?pretty" -d '
{
"query": {
"match": {
"name": {
"query": "SVF-123"
}
}
}
}
'
# Not analyzed according to `analyzer_keyword`, so matches. (Note: term, not match)
curl -XPOST "$ELASTICSEARCH_ENDPOINT/_search?pretty" -d '
{
"query": {
"term": {
"name": {
"value": "SVF-123"
}
}
}
}
'
curl -XPOST "$ELASTICSEARCH_ENDPOINT/_search?pretty" -d '
{
"query": {
"term": {
"_all": {
"value": "svf"
}
}
}
}
'
Run Code Online (Sandbox Code Playgroud)
Hüs*_*BAL 11
我的解决方案冒险
我已经开始了我的案子,你可以在我的问题中看到.每当我更改了部分设置时,一部分开始工作,但另一部分停止工作.让我给出我的解决方案历史:
1.)我已将我的数据编入索引为默认值.这意味着,我的数据是analyzed默认的.这会引起我的问题.例如;
当用户开始搜索SVF-1之类的关键字时,系统会运行以下查询:
{
"query": {
"filtered" : {
"query" : {
"query_string" : {
"analyze_wildcard": true,
"query": "*SVF-1*"
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
和结果;
SVF-123
SVF-234
Run Code Online (Sandbox Code Playgroud)
这是正常的,因为name我的文件的字段是analyzed.这种分裂查询分成记号SVF,并1和SVF我的文档匹配,即使1不匹配.我已经跳过了这种方式.我为我的字段创建了一个映射not_analyzed
{
"mappings":{
"product":{
"properties":{
"name":{
"type":"string",
"index": "not_analyzed"
},
"site":{
"type":"string",
"index": "not_analyzed"
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
但我的问题还在继续.
2.)经过大量研究,我想尝试另一种方式.决定使用通配符查询.我的疑问是;
{
"query": {
"wildcard" : {
"name" : {
"value" : *SVF-1*"
}
}
},
"filter":{
"term": {"site":"pro_en_GB"}
}
}
}
Run Code Online (Sandbox Code Playgroud)
这个查询有效,但这里有一个问题.我的字段不再被分析,我正在进行通配符查询.区分大小写是一个问题.如果我像svf-1一样搜索,它什么都不返回.因为,用户可以输入小写版本的查询.
3.)我已将文档结构更改为;
{
"mappings":{
"product":{
"properties":{
"name":{
"type":"string",
"index": "not_analyzed"
},
"nameLowerCase":{
"type":"string",
"index": "not_analyzed"
}
"site":{
"type":"string",
"index": "not_analyzed"
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我已经再加上一个字段用于name调用nameLowerCase.当我索引我的文档时,我正在设置我的文档;
{
name: "SVF-123",
nameLowerCase: "svf-123",
site: "pro_en_GB"
}
Run Code Online (Sandbox Code Playgroud)
在这里,我将查询关键字转换为小写,并对新nameLowerCase索引进行搜索操作.并显示name字段.
我的查询的最终版本是;
{
"query": {
"wildcard" : {
"nameLowerCase" : {
"value" : "*svf-1*"
}
}
},
"filter":{
"term": {"site":"pro_en_GB"}
}
}
}
Run Code Online (Sandbox Code Playgroud)
现在它有效.使用multi_field还有一种方法可以解决这个问题.我的查询包含破折号( - ),并遇到一些问题.
非常感谢@Alex Brasetvik的详细解释和努力
| 归档时间: |
|
| 查看次数: |
15967 次 |
| 最近记录: |