ElasticSearch: как искать в коллекции

У меня есть следующая структура объектов в ElasticSearch:

{
  _id: 1,
  myObj: {
    myCol: [{id: 1, name:"1"}, {id: 2, name:"2"}, {id: 3, name:"3"}]
  }
},
{
  _id: 2,
  myObj: {
    myCol: [{id: 2, name:"2"}, {id: 3, name:"3"}, {id: 4, name:"4"}]
  }
},

Я использую библиотеку С# NEST для создания запросов. Я хочу найти набор объектов myCol, используя набор идентификаторов.

Пример #1: Поисковый запрос: идентификаторы [2, 3] Результат: Возвращаются оба объекта

Пример #2: Поисковый запрос: идентификатор: [1] Результат: Возвращается первый объект

Пример №3: Поисковый запрос: идентификатор: [1, 2, 3, 4] Результат: Объекты не возвращаются


То, что я пытаюсь сделать, это запрос «Содержит все».

Пожалуйста, обрати внимание:

  1. Тип C# NEST MultiMatchQuery не поддерживает целочисленные массивы (только строки. Так плохо). Поэтому, пожалуйста, не предлагайте мне использовать этот тип запроса
  2. Я использую синтаксис запроса Object Initializer
  3. Достаточно правильного запроса в синтаксисе ElasticSearch.

person Ilya Schukin    schedule 29.09.2016    source источник
comment
Если я вас правильно понимаю, вам здесь не нужно ничего особенного — просто логический запрос с несколькими предложениями Must для myObj.myCol.id — коллекции в lucene сглажены, поэтому на самом деле у вас есть фактически дублирующиеся ключи, такие как myObj.myCol.id = 1 && myObj.myCol.id = 2 ...   -  person Ant P    schedule 29.09.2016
comment
Можете ли вы создать пример этого запроса в Elastic, пожалуйста?   -  person Ilya Schukin    schedule 29.09.2016


Ответы (1)


Что вам нужно, так это получить документы, которые содержат все указанные идентификаторы где-то в коллекции.

Когда вы используете коллекции объектов в ElasticSearch, они выравниваются, поэтому вы на самом деле индексируете что-то вроде следующего.

myObj.myCol.id = [ 2, 3, 4 ]
myObj.myCol.name = [ "2", "3", "4" ]

Во многих случаях это проблематично, потому что вы теряете отслеживание того, какие пары идентификатор/имя идут вместе (поэтому вы не можете, например, запросить документ, содержащий объект с идентификатором x и именем y — это приведет к ложным срабатываниям, если коллекция содержит x и y в разных объектах).

Однако в вашем случае это на самом деле выгодно, потому что вы можете просто запросить документы, содержащие все идентификаторы в myObj.myCol.id, например:

{
  "query": {
    "bool": {
      "must": [
        { "match": { "myObj.myCol.id": 1 }},
        { "match": { "myObj.myCol.id": 2 }}
      ]
    }
  }
}

Это вернет только документы, в которых myObj.myCol содержит объекты с идентификаторами как 1, так и 2.

Дополнительную информацию о том, как коллекции работают в ES, можно найти здесь< /а>.

person Ant P    schedule 29.09.2016
comment
К сожалению, это не работает. Запрос успешно выполняется с одним указанным идентификатором. Но когда я добавляю еще один - никаких результатов не возвращается - person Ilya Schukin; 29.09.2016
comment
@IlyaSchukin странно - если я проиндексирую опубликованные вами документы и использую этот запрос, он будет работать как положено. Может ли какая-то деталь, которую вы не опубликовали, повлиять на результаты запроса? Может быть, попробуйте вернуться к тому, что на самом деле находится в этом вопросе и ответе, и создать резервную копию оттуда. - person Ant P; 29.09.2016
comment
Ты был прав. Очень близко жесткий. Мне пришлось создать несколько вложенных запросов, но логический запрос внутри каждого из них - person Ilya Schukin; 30.09.2016
comment
@IlyaSchukin - А, у вас есть вложенные объекты в ваших сопоставлениях? - person Ant P; 30.09.2016