Как выполнить полнотекстовый поиск по числовым полям в ElasticSearch?
вопрос:
без преобразования числового поля в строку, как я могу выполнить полнотекстовый поиск на нем?
Я пытаюсь имитировать поведение _all
для динамического преобразования числового поля в строку при выполнении запроса.
пример.
настройка:
curl -XPUT http://localhost:9200/test/items/1 -d '{accountId : 12341234, name:"Bob"}'
curl -XPUT http://localhost:9200/test/items/2 -d '{accountId : 980987, name:"Marry"}'
curl -XPUT http://localhost:9200/test/items/3 -d '{accountId : 234234, name:"Daniel"}'
цель:
найти accountId
с номером 4.
что я сделал.
я попробовал эти два запроса, но получено 0 хиты.
запросы:
curl -XPOST "http://localhost:9200/test/items/_search" -d '{
"query": {
"term": {
"accountId": "4"
}
}
}'
curl -XPOST "http://localhost:9200/test/items/_search" -d '{
"query": {
"query_string": {
"query": "4"
}
}
}'
выход:
{
"took": 0,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 0,
"max_score": null,
"hits": []
}
}
2 ответов
Я предлагаю вам использовать токенизатор ngram для этой цели.
вот пример кода того, что вам может понадобиться. Сначала необходимо установить параметры анализатора с помощью токенизатора, который вы хотите использовать.
curl -XPUT localhost:9200/test?pretty=true -d '{
"settings":{
"analysis":{
"analyzer":{
"my_ngram_analyzer":{
"tokenizer":"my_ngram_tokenizer"
}
},
"tokenizer":{
"my_ngram_tokenizer":{
"type":"nGram",
"token_chars":[
"letter",
"digit"
]
}
}
}
}
}'
подробнее о Ngram Tokenizer здесь.
затем вы должны определить следующее сопоставление:
curl -XPUT localhost:9200/test/items/_mapping?pretty=true -d '{
"items":{
"properties":{
"accountId":{
"analyzer":"my_ngram_analyzer",
"type":"string"
},
"name":{
"type":"string"
}
}
}
}'
причина "accountId" является "строкой" в том, что токенизатор Ngram не работает на числовом поля.
Теперь вы можете запросить индекс :
curl -XGET localhost:9200/test/_search?pretty=true -d'
{
"query": {
"query_string": {
"default_field": "accountId",
"query": "4"
}
}
}'
вы можете найти здесь сценарий bash, который я использовал для его тестирования.
NB: конечно, это просто демо о том, как вы можете использовать Ngram Tokenizer. Надеюсь, это поможет
создать мульти-поле, которое будет содержать поле номер, а также строкой для поиска
PUT /test/items/_mapping
{
"items" : {
"properties" : {
"accountId" : {
"type" : "multi_field",
"fields" : {
"numeric" : {
"type" : "integer",
"index" : "not_analyzed"
},
"text" : {
"type" : "string",
"index" : "analyzed"
}
}
}
}
}
}
проверить отображение:
GET /test/items/_mapping
выход
{
"test": {
"mappings": {
"items": {
"properties": {
"accountId": {
"type": "integer",
"index": "no",
"fields": {
"numeric": {
"type": "integer"
},
"text": {
"type": "string"
}
}
}
}
}
}
}
}
Поместите свои данные в эластичный поиск.
теперь вы можете выполнить поиск как строка, но вы получите результат как номер:
GET /test/items/_search
{
"query": {
"query_string": {
"default_field": "accountId.text",
"query": "*4*"
}
}
}
выход
{
"took": 15,
"timed_out": false,
"_shards": {
"total": 4,
"successful": 4,
"failed": 0
},
"hits": {
"total": 2,
"max_score": 1,
"hits": [
{
"_index": "test",
"_type": "items",
"_id": "3",
"_score": 1,
"_source": {
"accountId": 234234,
"name": "Daniel"
}
},
{
"_index": "test",
"_type": "items",
"_id": "1",
"_score": 1,
"_source": {
"accountId": 12341234,
"name": "Bob"
}
}
]
}
}