在 Elasticsearch 中搜索带连字符的文本
Searching for hyphened text in Elasticsearch
我正在 elasticsearch 中存储一个 'Payment Reference Number'。
它的布局是例如:2-4-3-635844569819109531
或2-4-2-635844533758635433
等等
我希望能够通过
按付款参考号搜索文件
- 使用 'whole' 参考号搜索,例如输入
2-4-2-635844533758635433
- 任何'part'的参考号来自'start'。例如。
2-4-2-63
(..所以只有 return 示例中的第二个)
注意:我不想搜索 'in the middle' 或 'at the end' 等。只从头开始。
无论如何,连字符让我感到困惑。
问题
1) 我不确定是否应该像
这样在映射中删除它们
"char_filter" : {
"removeHyphen" : {
"type" : "mapping",
"mappings" : ["-=>"]
}
},
还是不行。我从来没有以这种方式使用映射,所以不确定是否有必要。
2) 我想我需要一个 'ngrams' 过滤器,因为我希望能够从存在中搜索参考编号的一部分。我觉得像
"partial_word":{
"filter":[
"standard",
"lowercase",
"name_ngrams"
],
"type":"custom",
"tokenizer":"whitespace"
},
和过滤器
"name_ngrams":{
"side":"front",
"max_gram":50,
"min_gram":2,
"type":"edgeNGram"
},
我不确定如何将它们放在一起但是
"paymentReference":{
"type":"string",
"analyzer": "??",
"fields":{
"partial":{
"search_analyzer":"???",
"index_analyzer":"partial_word",
"type":"string"
}
}
}
在第二个搜索案例中,我尝试过的一切似乎总是 'break'。
如果我这样做 'localhost:9200/orders/_analyze?field=paymentReference&pretty=1' -d "2-4-2-635844533758635433"
它总是打破连字符,因为它是自己的标记和 returns 例如所有带 2-
的文档都是 'alot'!而不是我在搜索 2-4-2-6
时想要的
有人可以告诉我如何为我要实现的两种搜索类型映射此字段吗?
更新-回答
实际上是 Val 在下面所说的。我只是稍微更改了映射,以便更具体地重新分析分析器,而且我不需要索引主字符串,因为我只查询部分字符串。
映射
"paymentReference":{
"type": "string",
"index":"not_analyzed",
"fields": {
"partial": {
"search_analyzer":"payment_ref",
"index_analyzer":"payment_ref",
"type":"string"
}
}
}
分析仪
"payment_ref": {
"type": "custom",
"filter": [
"lowercase",
"name_ngrams"
],
"tokenizer": "keyword"
}
过滤器
"name_ngrams":{
"side":"front",
"max_gram":50,
"min_gram":2,
"type":"edgeNGram"
},
您不需要为此使用映射字符过滤器。
您使用 Edge NGram 标记过滤器的方向正确,因为您只需要能够搜索前缀。我会改用 keyword
分词器来确保该术语被视为一个整体。所以设置方法是这样的:
curl -XPUT localhost:9200/orders -d '{
"settings": {
"analysis": {
"analyzer": {
"partial_word": {
"type": "custom",
"filter": [
"lowercase",
"ngram_filter"
],
"tokenizer": "keyword"
}
},
"filter": {
"ngram_filter": {
"type": "edgeNGram",
"min_gram": 2,
"max_gram": 50
}
}
}
},
"mappings": {
"order": {
"properties": {
"paymentReference": {
"type": "string",
"fields": {
"partial": {
"analyzer": "partial_word",
"type": "string"
}
}
}
}
}
}
}'
然后您可以分析将要索引到您的 paymentReference.partial
字段的内容:
curl -XGET 'localhost:9205/payments/_analyze?field=paymentReference.partial&pretty=1' -d "2-4-2-635844533758635433"
你得到的正是你想要的,即所有前缀:
{
"tokens" : [ {
"token" : "2-",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
"token" : "2-4",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
"token" : "2-4-",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
"token" : "2-4-2",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
"token" : "2-4-2-",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
"token" : "2-4-2-6",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
"token" : "2-4-2-63",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
"token" : "2-4-2-635",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
"token" : "2-4-2-6358",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
"token" : "2-4-2-63584",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
...
终于可以搜索任意前缀了:
curl -XGET localhost:9200/orders/order/_search?q=paymentReference.partial:2-4-3
不确定通配符搜索是否符合您的需要。我定义自定义过滤器并设置 preserve_original 并生成错误的数字部分。这是示例代码:
PUT test1
{
"settings" : {
"analysis" : {
"analyzer" : {
"myAnalyzer" : {
"type" : "custom",
"tokenizer" : "whitespace",
"filter" : [ "dont_split_on_numerics" ]
}
},
"filter" : {
"dont_split_on_numerics" : {
"type" : "word_delimiter",
"preserve_original": true,
"generate_number_parts" : false
}
}
}
},
"mappings": {
"type_one": {
"properties": {
"title": {
"type": "text",
"analyzer": "standard"
}
}
},
"type_two": {
"properties": {
"raw": {
"type": "text",
"analyzer": "myAnalyzer"
}
}
}
}
}
POST test1/type_two/1
{
"raw": "2-345-6789"
}
GET test1/type_two/_search
{
"query": {
"wildcard": {
"raw": "2-345-67*"
}
}
}
我正在 elasticsearch 中存储一个 'Payment Reference Number'。
它的布局是例如:2-4-3-635844569819109531
或2-4-2-635844533758635433
等等
我希望能够通过
按付款参考号搜索文件- 使用 'whole' 参考号搜索,例如输入
2-4-2-635844533758635433
- 任何'part'的参考号来自'start'。例如。
2-4-2-63
(..所以只有 return 示例中的第二个)
注意:我不想搜索 'in the middle' 或 'at the end' 等。只从头开始。
无论如何,连字符让我感到困惑。
问题
1) 我不确定是否应该像
这样在映射中删除它们"char_filter" : {
"removeHyphen" : {
"type" : "mapping",
"mappings" : ["-=>"]
}
},
还是不行。我从来没有以这种方式使用映射,所以不确定是否有必要。
2) 我想我需要一个 'ngrams' 过滤器,因为我希望能够从存在中搜索参考编号的一部分。我觉得像
"partial_word":{
"filter":[
"standard",
"lowercase",
"name_ngrams"
],
"type":"custom",
"tokenizer":"whitespace"
},
和过滤器
"name_ngrams":{
"side":"front",
"max_gram":50,
"min_gram":2,
"type":"edgeNGram"
},
我不确定如何将它们放在一起但是
"paymentReference":{
"type":"string",
"analyzer": "??",
"fields":{
"partial":{
"search_analyzer":"???",
"index_analyzer":"partial_word",
"type":"string"
}
}
}
在第二个搜索案例中,我尝试过的一切似乎总是 'break'。
如果我这样做 'localhost:9200/orders/_analyze?field=paymentReference&pretty=1' -d "2-4-2-635844533758635433"
它总是打破连字符,因为它是自己的标记和 returns 例如所有带 2-
的文档都是 'alot'!而不是我在搜索 2-4-2-6
有人可以告诉我如何为我要实现的两种搜索类型映射此字段吗?
更新-回答
实际上是 Val 在下面所说的。我只是稍微更改了映射,以便更具体地重新分析分析器,而且我不需要索引主字符串,因为我只查询部分字符串。
映射
"paymentReference":{
"type": "string",
"index":"not_analyzed",
"fields": {
"partial": {
"search_analyzer":"payment_ref",
"index_analyzer":"payment_ref",
"type":"string"
}
}
}
分析仪
"payment_ref": {
"type": "custom",
"filter": [
"lowercase",
"name_ngrams"
],
"tokenizer": "keyword"
}
过滤器
"name_ngrams":{
"side":"front",
"max_gram":50,
"min_gram":2,
"type":"edgeNGram"
},
您不需要为此使用映射字符过滤器。
您使用 Edge NGram 标记过滤器的方向正确,因为您只需要能够搜索前缀。我会改用 keyword
分词器来确保该术语被视为一个整体。所以设置方法是这样的:
curl -XPUT localhost:9200/orders -d '{
"settings": {
"analysis": {
"analyzer": {
"partial_word": {
"type": "custom",
"filter": [
"lowercase",
"ngram_filter"
],
"tokenizer": "keyword"
}
},
"filter": {
"ngram_filter": {
"type": "edgeNGram",
"min_gram": 2,
"max_gram": 50
}
}
}
},
"mappings": {
"order": {
"properties": {
"paymentReference": {
"type": "string",
"fields": {
"partial": {
"analyzer": "partial_word",
"type": "string"
}
}
}
}
}
}
}'
然后您可以分析将要索引到您的 paymentReference.partial
字段的内容:
curl -XGET 'localhost:9205/payments/_analyze?field=paymentReference.partial&pretty=1' -d "2-4-2-635844533758635433"
你得到的正是你想要的,即所有前缀:
{
"tokens" : [ {
"token" : "2-",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
"token" : "2-4",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
"token" : "2-4-",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
"token" : "2-4-2",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
"token" : "2-4-2-",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
"token" : "2-4-2-6",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
"token" : "2-4-2-63",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
"token" : "2-4-2-635",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
"token" : "2-4-2-6358",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
"token" : "2-4-2-63584",
"start_offset" : 0,
"end_offset" : 24,
"type" : "word",
"position" : 1
}, {
...
终于可以搜索任意前缀了:
curl -XGET localhost:9200/orders/order/_search?q=paymentReference.partial:2-4-3
不确定通配符搜索是否符合您的需要。我定义自定义过滤器并设置 preserve_original 并生成错误的数字部分。这是示例代码:
PUT test1
{
"settings" : {
"analysis" : {
"analyzer" : {
"myAnalyzer" : {
"type" : "custom",
"tokenizer" : "whitespace",
"filter" : [ "dont_split_on_numerics" ]
}
},
"filter" : {
"dont_split_on_numerics" : {
"type" : "word_delimiter",
"preserve_original": true,
"generate_number_parts" : false
}
}
}
},
"mappings": {
"type_one": {
"properties": {
"title": {
"type": "text",
"analyzer": "standard"
}
}
},
"type_two": {
"properties": {
"raw": {
"type": "text",
"analyzer": "myAnalyzer"
}
}
}
}
}
POST test1/type_two/1
{
"raw": "2-345-6789"
}
GET test1/type_two/_search
{
"query": {
"wildcard": {
"raw": "2-345-67*"
}
}
}