Ваше отображение индекса эластичного поиска для вышеуказанной структуры данных должно быть:
Отображение
{
"mappings": {
"properties": {
"did_user_read": {
"type": "boolean"
},
"view_info": {
"properties": {
"total": {
"type": "integer"
},
"users": {
"properties": {
"name": {
"type": "text"
},
"read_at": {
"type": "date",
"format": "date_hour_minute_second"
},
"is_current_user": {
"type": "boolean"
}
}
}
}
},
"is_favorite": {
"type": "boolean"
},
"has_attachments": {
"type": "boolean"
},
"from": {
"properties": {
"short_name": {
"type": "text"
},
"full_name": {
"type": "text"
},
"email": {
"type": "keyword"
},
"is_current_user": {
"type": "boolean"
}
}
},
"subject": {
"type": "text"
},
"received_at": {
"type": "date",
"format": "date_hour_minute_second"
}
}
}
}
Теперь я проиндексировал несколько документов в том же формате, который вы дали в ваш пример.
Поисковый запрос на основе заданных критериев должен быть:
Поисковый запрос:
{
"query": {
"bool": {
"filter": [
{
"term": {
"is_favorite": false
}
},
{
"term": {
"view_info.users.is_current_user": true
}
}
],
"must": {
"multi_match": {
"query": "sam jackson",
"fields": [
"view_info.users.name",
"from.full_name",
"from.short_name"
]
}
}
}
},
"sort": [
{
"received_at": {
"order": "desc"
}
}
]
}
Вывод
"hits": [
{
"_index": "topics",
"_type": "_doc",
"_id": "3",
"_score": null,
"_source": {
"did_user_read": true,
"view_info": {
"total": 1,
"users": [
{
"name": "John Smith",
"read_at": "2020-02-04T11:00:01",
"is_current_user": false
},
{
"name": "Samuel Jackson",
"read_at": "2020-02-04T11:00:01",
"is_current_user": true
}
]
},
"is_favorite": false,
"has_attachments": true,
"from": {
"short_name": "You",
"full_name": "Chuck Norris",
"email": "ch.norris@example.com",
"is_current_user": true
},
"subject": "The secret of the appearance of navel lints",
"received_at": "2020-02-04T11:00:03"
},
"sort": [
1580814003000
]
},
{
"_index": "topics",
"_type": "_doc",
"_id": "2",
"_score": null,
"_source": {
"did_user_read": true,
"view_info": {
"total": 1,
"users": [
{
"name": "John Smith",
"read_at": "2020-02-04T11:00:01",
"is_current_user": false
},
{
"name": "Samuel Jackson",
"read_at": "2020-02-04T11:00:01",
"is_current_user": true
}
]
},
"is_favorite": false,
"has_attachments": true,
"from": {
"short_name": "You",
"full_name": "Chuck Norris",
"email": "ch.norris@example.com",
"is_current_user": true
},
"subject": "The secret of the appearance of navel lints",
"received_at": "2020-02-04T11:00:01"
},
"sort": [
1580814001000
]
}
]
Объяснение:
На основе вашего запроса строится поисковый запрос:
is_favorite IS false and users.is_current_user IS NOT false
Это делается с помощью запроса filter
. Фильтр используется, когда мы хотим, чтобы наши документы удовлетворяли некоторым условиям, но они не влияют на оценку результатов поиска документов. Теперь, поскольку оба поля запроса являются булевыми, они не будут вносить вклад в вычисление для оценки, поскольку ответ будет либо да, либо нет.
FULL_TEXT_SEARCH("sam jackson")
BY FIELDS
users.name, -- inside of array(!)
from.full_name,
from.short_name
Здесь мы хотим выполнить поиск sam jackson
и они должны быть во всех 3 полях, поэтому используется match_phrase
.
Эти три условия сохраняются в фильтре bool
, поскольку к ним присоединяется условие AND
ПРИМЕЧАНИЕ : Вы должны изменить ваши данные, где datetime присутствует, как в read_at, receive_at. В настоящее время вы принимаете формат как 2020-02-04 11:00:01. Вам просто нужно немного изменить, чтобы при индексировании документов вasticsearch он принимал формат 2020-02-04T11: 00: 01 (вместо пробела используйте T), так какasticsearch принимает только набор форматов даты и времени. Вы можете ознакомиться с форматами, принятыми по дате / времени здесь https://www.elastic.co/guide/en/elasticsearch/reference/current/mapping-date-format.html