Фильтровать результаты ElasticSearch на основе И условия в массиве

#database #elasticsearch #elastic-stack

#База данных #elasticsearch #эластичный стек

Вопрос:

Ниже приведен образец данных одной записи в моем индексе:

 {
        "_index" : "test_index",
        "_type" : "_doc",
        "_id" : "49605102905391763685971719283371021096086998966740189186",
        "_score" : 2.8858113,
        "_source" : {
          "properties" : {
            "activity" : [
              {
                "activityId" : 39,
                "actionVersion" : 2,
                "actionIdx" : 3
              },
              {
                "activityId" : 39,
                "actionVersion" : 2,
                "actionIdx" : 4
              },
              {
                "activityId" : 39,
                "actionVersion" : 2,
                "actionIdx" : 5
              },
              {
                "activityId" : 42,
                "actionVersion" : 2,
                "actionIdx" : 3
              },
              {
                "activityId" : 42,
                "actionVersion" : 2,
                "actionIdx" : 4
              },
              {
                "activityId" : 42,
                "actionVersion" : 2,
                "actionIdx" : 5
              }
            ]
          }
        }
      }
  

Я хочу фильтровать результаты на основе activitiyId 42 и actionIdx 3. Я использую приведенный ниже запрос, пытаясь получить результаты.

 {"size":-1,
  "query": {
    "bool": {
            "should": {
                "bool": {
                    "must": [
                        {
                            "match": {
                                "activityId": 42
                            }
                        },
                        {
                            "match": {
                                "actionIdx": 3
                            }
                        }
                        
                        
                    ]
                }
            }
        }
  }
}
  

Я получаю записи, содержащие activityid 42 и actionidx 3, но мое требование — иметь записи, содержащие activity 42 и actionidx 3 в одном объекте. Ниже приведены мои результаты с приведенным выше поисковым запросом:

       "activity" : [
              {
                "activityId" : 39,
                "actionVersion" : 2,
                "actionIdx" : 2
              },
              {
                "activityId" : 28,
                "actionVersion" : 2,
                "actionIdx" : 3
              },
              {
                "activityId" : 42,
                "actionVersion" : 2,
                "actionIdx" : 2
              },
              {
                "activityId" : 41,
                "actionVersion" : 2,
                "actionIdx" : 3
              }
            ]
  

Мой ожидаемый результат должен быть:

 "activity" : [
              {
                "activityId" : 39,
                "actionVersion" : 2,
                "actionIdx" : 2
              },
              {
                "activityId" : 28,
                "actionVersion" : 2,
                "actionIdx" : 3
              },
              {
                "activityId" : 42,
                "actionVersion" : 2,
                "actionIdx" : 3
              }
            ]
  

Вот индекс сопоставления. Действие не является вложенным

 "properties" : {
            "properties" : {
              "activity" : {
                "properties" : {
                  "actionIdx" : {
                    "type" : "long"
                  },
                  "actionVersion" : {
                    "type" : "long"
                  },
                  "activityId" : {
                    "type" : "long"
                  }
                }
              }
            }
          }
  

Комментарии:

1. Можете ли вы предоставить свое отображение индекса? Я работаю над вашим поисковым запросом и приведу рабочий пример

2. Привет @OpsterElasticsearchNinja, я попытался создать новый индекс с вложенным типом object, но все еще сталкиваюсь с проблемой неполучения результатов.

3. Я привел полный пример вложенного типа, вы пробовали это?

Ответ №1:

вам нужно использовать вложенный тип данных и запрос для достижения этого, прямо сейчас, поскольку вы его не используете, он рассматривается как объектный тип данных (по умолчанию), и во вложенных документах четко упоминается проблема, с которой вы столкнулись.

При вводе пар ключ-значение с большим произвольным набором ключей можно рассмотреть возможность моделирования каждой пары ключ-значение как отдельного вложенного документа с полями ключ-значение. Вместо этого рассмотрите возможность использования сглаженного типа данных, который отображает весь объект как одно поле и позволяет выполнять простой поиск по его содержимому. Вложенные документы и запросы обычно дороги, поэтому использование сглаженного типа данных для этого варианта использования является лучшим вариантом.

Отображение индекса

     {
  "mappings": {
    "properties": {
      "properties": {
        "properties": {
          "activity": {
            "type": "nested"
          }
        }
      }
    }
  }
}
  

Индексировать данные:

 {
    "properties": {
        "activity": [
            {
                "activityId": 39,
                "actionVersion": 2,
                "actionIdx": 3
            },
            {
                "activityId": 39,
                "actionVersion": 2,
                "actionIdx": 4
            },
            {
                "activityId": 39,
                "actionVersion": 2,
                "actionIdx": 5
            },
            {
                "activityId": 42,
                "actionVersion": 2,
                "actionIdx": 3
            },
            {
                "activityId": 42,
                "actionVersion": 2,
                "actionIdx": 4
            },
            {
                "activityId": 42,
                "actionVersion": 2,
                "actionIdx": 5
            }
        ]
    }
}
  

Поисковый запрос:

 {
  "query": {
    "nested": {
      "path": "properties.activity",
      "query": {
        "bool": {
          "must": [
            {
              "match": {
                "properties.activity.activityId": 42
              }
            },
            {
              "match": {
                "properties.activity.actionIdx": 3
              }
            }
          ]
        }
      },
      "inner_hits":{}
    }
  }
}
  

Результат поиска

  "hits": [
                {
                  "_index": "fd_cb1",
                  "_type": "_doc",
                  "_id": "1",
                  "_nested": {
                    "field": "properties.activity",
                    "offset": 3
                  },
                  "_score": 2.0,
                  "_source": {
                    "activityId": 42,
                    "actionVersion": 2,
                    "actionIdx": 3
                  }
                }
              ]
  

Комментарии:

1. Привет, я пробовал запрос, но он все еще не работает. Также отображение для activity не является вложенным.