Вы должны использовать Ngram Tokenizer , так как поиск по шаблону не должен использоваться из соображений производительности, и я бы не рекомендовал его использовать.
Измените ваше сопоставление на приведенное ниже, где вы можете создать свой собственный Анализатор , который я сделал в приведенном ниже сопоставлении.
Как эластичный поиск (albiet lucene) индексирует утверждениесначала он разбивает оператор или абзац на слова или токены, затем индексирует эти слова в инвертированном индексе для этого конкретного поля. Этот процесс называется Анализ , и он будет применим только к типу данных text
.
Так что теперь вы получаете документы, только если эти токены доступны в инвертированном индексе.
По умолчанию будет применяться стандартный анализатор . Я создал свой собственный анализатор и использовал Ngram Tokenizer, который создавал бы намного больше токенов, чем просто слова.
Анализатор по умолчанию для Life is beautiful
будет life
, is
, beautiful
.
Однако при использовании Ngrams токены для Life
будут lif
, ife
& life
Mapping:
PUT student_detail
{
"settings": {
"analysis": {
"analyzer": {
"my_analyzer": {
"tokenizer": "my_tokenizer"
}
},
"tokenizer": {
"my_tokenizer": {
"type": "ngram",
"min_gram": 3,
"max_gram": 4,
"token_chars": [
"letter",
"digit"
]
}
}
}
},
"mappings" : {
"properties" : {
"id" : {
"type" : "long"
},
"name" : {
"type" : "text",
"analyzer": "my_analyzer",
"fields": {
"keyword": {
"type": "keyword"
}
}
},
"email" : {
"type" : "text",
"analyzer": "my_analyzer",
"fields": {
"keyword": {
"type": "keyword"
}
}
},
"age" : {
"type" : "text" <--- I am not sure why this is text. Change it to long or int. Would leave this to you
},
"status" : {
"type" : "text",
"analyzer": "my_analyzer",
"fields": {
"keyword": {
"type": "keyword"
}
}
},
"tests":{
"type" : "nested"
}
}
}
}
Обратите внимание, что ввыше сопоставления я создал одноуровневое поле в форме ключевого слова для name
, email
и status
, как показано ниже:
"name":{
"type":"text",
"analyzer":"my_analyzer",
"fields":{
"keyword":{
"type":"keyword"
}
}
}
Теперь ваш запрос может быть простым, как показано ниже.
Запрос:
POST student_detail/_search
{
"query": {
"bool": {
"must": [
{
"match": {
"name": "war" <---- Note this. This would even return documents having "Schwarb"
}
},
{
"match": {
"email": "gmail" <---- Note this
}
},
{
"nested": {
"path": "tests",
"query": {
"bool": {
"must": [
{
"term": {
"tests.test_id": 587
}
},
{
"range": {
"tests.test_score": {
"gte": 5
}
}
}
]
}
}
}
}
]
}
}
}
Обратите внимание, что для точных совпадений я бы использовал Запросы терминов для ключевых слов полей, в то время как для обычного поиска или LIKE
в SQL
я бы использовал простые запросы на совпадение на текст поля при условии они используют Ngram Tokenizer
.
Также обратите внимание, что для >=
и <=
вам потребуется использовать Range Query .
Ответ:
{
"took" : 233,
"timed_out" : false,
"_shards" : {
"total" : 1,
"successful" : 1,
"skipped" : 0,
"failed" : 0
},
"hits" : {
"total" : {
"value" : 1,
"relation" : "eq"
},
"max_score" : 3.7260926,
"hits" : [
{
"_index" : "student_detail",
"_type" : "_doc",
"_id" : "1",
"_score" : 3.7260926,
"_source" : {
"id" : 123,
"name" : "Schwarb",
"email" : "abc@gmail.com",
"status" : "current",
"age" : 14,
"tests" : [
{
"test_id" : 587,
"test_score" : 10
},
{
"test_id" : 588,
"test_score" : 6
}
]
}
}
]
}
}
Обратите внимание, что я наблюдаю документ, который вы упомянули в своем вопросе, в моем ответе, когда я запускаю запрос.
Пожалуйста, прочитайте ссылки, которыми я поделился. Важно, чтобы вы поняли концепции. Надеюсь, это поможет!