我想对QNMZ-1900
当我在文档中阅读并亲自尝试时,Elasticsearch的标准标记生成器会将连字符上的单词拆分,例如QNMZ-1900
将分为QNMZ
和1900
。< / p>
为防止出现这种情况,我使用了not_analyzed
功能。
curl -XPUT 'localhost:9200/test-idx' -d '{
"mappings": {
"doc": {
"properties": {
"foo" : {
"type": "string",
"index": "not_analyzed"
}
}
}
}
}'
我在我的索引中添加了一些内容:
curl -XPUT 'localhost:9200/test-idx/doc/1' -d '{"foo": "QNMZ-1900"}'
刷新它:
curl -XPOST 'localhost:9200/test-idx/_refresh'
现在我可以使用通配符查询并找到QNMZ-1900
:
curl 'localhost:9200/test-idx/doc/_search?pretty=true' -d '{
"query": {
"wildcard" : { "foo" : "QNMZ-19*" }
}
我的问题:
如何使用小写搜索字词运行通配符查询?
我试过了:
curl -XDELETE 'localhost:9200/test-idx'
curl -XPUT 'localhost:9200/test-idx' -d '{
"mappings": {
"doc": {
"properties": {
"foo" : {
"type": "string",
"index": "not_analyzed",
"filter": "lowercase"
}
}
}
}
}'
curl -XPUT 'localhost:9200/test-idx/doc/1' -d '{"foo": "QNMZ-1900"}'
curl -XPOST 'localhost:9200/test-idx/_refresh'
但我的小写查询:
curl 'localhost:9200/test-idx/doc/_search?pretty=true' -d '{
"query": {
"wildcard" : { "foo" : "qnmz-19*" }
}
}'
找不到任何东西。
如何解决?
答案 0 :(得分:4)
一种解决方案是使用
定义自定义分析器keyword
标记生成器(保持输入值不变,好像是not_analyzed
)lowercase
tokenfilter 我试过这个:
POST test-idx
{
"index":{
"analysis":{
"analyzer":{
"lowercase_hyphen":{
"type":"custom",
"tokenizer":"keyword",
"filter":["lowercase"]
}
}
}
}
}
PUT test-idx/doc/_mapping
{
"doc":{
"properties": {
"foo" : {
"type": "string",
"analyzer": "lowercase_hyphen"
}
}
}
}
POST test-idx/doc
{
"foo":"QNMZ-1900"
}
正如您所看到的那样使用_analyze端点:
GET test-idx/_analyze?analyzer=lowercase_hyphen&text=QNMZ-1900
只输出一个小写的标记但不在连字符上分割:
{
"tokens": [
{
"token": "qnmz-1900",
"start_offset": 0,
"end_offset": 9,
"type": "word",
"position": 1
}
]
}
然后,使用相同的查询:
POST test-idx/doc/_search
{
"query": {
"wildcard" : { "foo" : "qnmz-19*" }
}
}
我有这个结果,这就是你想要的:
{
"took": 66,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 1,
"max_score": 1,
"hits": [
{
"_index": "test-idx",
"_type": "doc",
"_id": "wo1yanIjQGmvgfScMg4hyg",
"_score": 1,
"_source": {
"foo": "QNMZ-1900"
}
}
]
}
}
但请注意,这样您只能使用小写值进行查询。
正如Andrei在评论中所述,具有值QNMZ-19*
的相同查询不会返回任何内容。
原因可以在documentation中找到:在搜索时,不会分析该值。
答案 1 :(得分:0)
我在基于ES 6.1的宠物项目中检查了这个方法。如下所示的数据模型允许按预期搜索:
PUT test-idx
{
"settings": {
"analysis": {
"analyzer": {
"keylower": {
"type": "custom",
"tokenizer": "keyword",
"filter": ["lowercase"]
}
}
}
}
}
POST /test-idx/doc/_mapping
{
"properties": {
"foo": {
"type": "text",
"fields": {
"raw": {
"type": "keyword"
},
"lowercase_foo": {
"type": "text",
"analyzer": "keylower"
}
}
}
}
}
PUT /test-idx/doc/1
{"foo": "QNMZ-1900"}
检查这两次搜索的结果。首先将重新打击一击。第二个将返回0次点击。
GET /test-idx/doc/_search
{
"query": {
"wildcard" : { "foo.lowercase_foo" : "qnmz-19*" }
}
}
GET /test-idx/doc/_search
{
"query": {
"wildcard" : { "foo" : "qnmz-19*" }
}
}
感谢@ThomasC的意见。请小心我的回答。我刚刚学习Elasticsearch。我不是这个数据库的专家。我不知道它是生产就绪的建议!