NEST: как запрашивать несколько индексов и обрабатывать разные подклассы (типы документов)?

Я играю с ElasticSearch в сочетании с NEST в моем проекте С#. В моем примере использования есть несколько индексов с разными типами документов, которые я запрашиваю отдельно до сих пор. Теперь я хочу реализовать глобальную функцию поиска, которая запрашивает все существующие индексы, типы документов и правильно оценивает результат.

Итак, мой вопрос: как это сделать, используя NEST?

В настоящее время я использую функцию SetDefaultIndex, но как определить несколько индексов?

Возможно, для лучшего понимания, это запрос, который я хочу реализовать с помощью NEST:

{
  "query": {
    "indices": {
      "indices": [
        "INDEX_A",
        "INDEX_B"
      ],
      "query": {
        "term": {
          "FIELD": "VALUE"
        }
      },
      "no_match_query": {
        "term": {
          "FIELD": "VALUE"
        }
      }
    }
  }
}

ТИА

Ответ 1

Вы можете явно указать NEST использовать несколько индексов:

client.Search<MyObject>(s=>s
    .Indices(new [] {"Index_A", "Index_B"})
    ...
)

Если вы хотите искать по всем индексам

client.Search<MyObject>(s=>s
    .AllIndices()
    ...
)

Или если вы хотите найти один индекс (это не индекс по умолчанию)

client.Search<MyObject>(s=>s.
    .Index("Index_A")
    ...
)

Помните, что после elasticsearch 19.8 вы также можете указать подстановочные знаки в именах индексов

client.Search<MyObject>(s=>s
    .Index("Index_*")
    ...
)

Что касается вашего indices_query

client.Search<MyObject>(s=>s
    .AllIndices()
    .Query(q=>q
        .Indices(i=>i
            .Indices(new [] { "INDEX_A", "INDEX_B"})
            .Query(iq=>iq.Term("FIELD","VALUE"))
            .NoMatchQuery(iq=>iq.Term("FIELD", "VALUE"))
        )
    )
);

UPDATE

Эти тесты показывают, как вы можете сделать ковариацию С# для вас:

https://github.com/Mpdreamz/NEST/blob/master/src/Nest.Tests.Integration/Search/SubClassSupport/SubClassSupportTests.cs

В вашем случае, если все типы не являются подклассами общей базы, вы все равно можете использовать "объект"

то есть:

 .Search<object>(s=>s
      .Types(typeof(Product),typeof(Category),typeof(Manufacturer))
      .Query(...)
 );

Это будет поиск по /yourdefaultindex/products,categories,manufacturers/_search и настройка по умолчанию ConcreteTypeSelector, который понимает, какой тип каждого возвращаемого документа есть.

Используя ConcreteTypeSelector(Func<dynamic, Hit<dynamic>, Type>), вы можете вручную вернуть тип, основанный на некотором значении json (в динамическом режиме) или метаданных попадания.