#elasticsearch #elasticsearch-5 #elasticsearch-dsl
#elasticsearch #elasticsearch-5 #elasticsearch-dsl
Вопрос:
Попытка создать запрос для таких документов, как:
{
"name" : "Bob",
"grades" : [
{
"year" : 2010,
"grade": 8,
},
{
"year" : 2018,
"grade": 7,
},
{
"year" : 2019,
"grade": 4,
}
]
},
{
"name" : "Alice",
"grades" : [
{
"year" : 2005,
"grade": 3,
},
{
"year" : 2016,
"grade": 8,
},
{
"year" : 2018,
"grade": 7,
},
{
"year" : 2019,
"grade": 6,
}
]
}
У меня есть диапазон лет, например, с 2010 по 2020 год. Запрос должен возвращать документ, если для всех доступных лет (в документе) в диапазоне (с 2010 по 2020 год) оценки> 5. Если есть оценки <= 5 за пределами интересующего диапазона лет, нам все равно, и это никоим образом не должно повлиять на конечный результат. Таким образом, в основном должен быть возвращен только документ с Алисой. Изучив документацию Elasticsearch, не могу найти решение (скорее всего, я просто что-то пропустил). Я могу создать запрос, если в годах нет пробелов, но в моем случае есть пробелы. Поэтому мой запрос просто отбрасывает такие документы. Текущий запрос:
{
"query": {
"bool": {
"must": [
{
"nested": {
"query": {
"bool": {
"must": [
{
"term": {
"grades.year": {"value": 2010}
}
},
{
"range": {
"grades.grade": {"from": 5}
}
}
]
}
},
"path": "grades"
}
},
{
"nested": {
"query": {
"bool": {
"must": [
{
"term": {
"grades.year": {"value": 2011}
}
},
{
"range": {
"grades.grade": {"from": 5}
}
}
]
}
},
"path": "grades"
}
},
....
]
}
}
}
Возможно, я определенно что-то пропустил. Возможно ли это?
Обновить
Я добавил 2005 год с оценкой 3 к оценкам Алисы. Итак, теперь Алиса все еще должна быть сопоставлена, поскольку 2005 год находится за пределами интересующего диапазона.
Спасибо!
Ответ №1:
Вы можете использовать must_not
предложение, которое исключит все документы, содержащие оценку меньше или равную 5
Поисковый запрос:
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "grades",
"query": {
"bool": {
"must": [
{
"range": {
"grades.year": {
"gte": 2010,
"lte": 2020
}
}
}
]
}
}
}
}
],
"must_not": {
"nested": {
"path": "grades",
"query": {
"bool": {
"must": [
{
"range": {
"grades.grade": {
"lte": 5
}
}
}
]
}
}
}
}
}
}
}
Результат поиска:
"hits": [
{
"_index": "64882747",
"_type": "_doc",
"_id": "2",
"_score": 1.0,
"_source": {
"name": "Alice",
"grades": [
{
"year": 2016,
"grade": 8
},
{
"year": 2018,
"grade": 7
},
{
"year": 2019,
"grade": 6
}
]
}
}
]
Комментарии:
1. Спасибо! Это действительно полезно и почти делает то, что мне нужно. Но, по-видимому, он удаляет документ, если хотя бы один год имеет класс lte 5. Если есть год, который находится за пределами интересующего диапазона, нас не должно волновать, является ли класс lte 5. Я обновил свой вопрос. Спасибо!
2. @Zanas_x3 но год
2005
находится за пределами диапазона, иgrade
он также меньше, чем5
, тем не менее, вы хотите, чтобы этотAlice
документ соответствовал?3. Именно так. Нас интересуют только оценки, которые находятся в диапазоне [2010, 2020]. Если оценка была меньше 5 давным-давно, нам действительно все равно. Я отредактирую свой вопрос, чтобы быть более понятным, извините за путаницу. Спасибо!
4. @Zanas_x3 спасибо за ваш ответ 🙂 Позвольте мне посмотреть, смогу ли я найти способ реализовать ваш вариант использования
5. Спасибо, Бхавья! Вы помогли мне, указав правильный путь. Взгляните на мое решение, похоже, оно делает то, что должно. Надеюсь…
Ответ №2:
Похоже, я нашел решение! Спасибо @Bhavya за то, что направил меня. В основном используется некоторая дополнительная логическая логика. В итоге я получил следующий запрос:
{
"query": {
"bool": {
"must": [
{
"nested": {
"path": "grades",
"query": {
"bool": {
"must": [
{
"range": {
"grades.year": {
"gte": 2010,
"lte": 2020
}
}
}
]
}
}
}
}
],
"must_not": {
"nested": {
"path": "grades",
"query": {
"bool": {
"should": [
{
"bool": {
"must": [
{
"term": {
"grades.year": {
"value": 2010
}
}
},
{
"range": {
"grades.grade": {
"lte": 5
}
}
}
]
}
},
...
...
...
...
...
]
}
}
}
}
}
}
}