Как сопоставить один тип .NET с несколькими типами вложенных объектов в ElasticSearch/NEST?

Я использую библиотеку NEST для взаимодействия с ElasticSearch, и я пытаюсь выяснить способ создания типов индексов/вложенных объектов на основе данных, отличных от типа. Тип имеет следующую базовую структуру.

 public class Entity : DynamicObject
 {
        public string Id { get; set; }
        // a bunch of other simple properties

        public override IEnumerable<string> GetDynamicMemberNames()
        {
                return Data.Select(x => x.Name);
        }

        public override bool TryGetMember(GetMemberBinder binder, out object result)
        {

            var dictionary = Data.First(x => x.Name == binder.Name);
            result = dictionary;
            return true;
        }

        // each instance of one these should be a nested object type
        public IList<NestedType> Data { get; set; } 

        public class NestedType
        {
            // How do I make Name be the nest type name?
            public string Name { get; set; }
            public IDictionary<string, string> Values { get; set; } 
        }
}

Я хочу создать вложенный объект/тип для каждого экземпляра NestedType. Итак, если есть два экземпляра NestedType, тогда будут два вложенных объекта. Я могу наследовать NestedType из DynamicObject, чтобы превратить словарь в "реальные" свойства, которые NEST затем правильно отображает (т.е. Превращает каждый ключ словаря в свойство). Проблема в том, что я не могу понять, как установить имя/тип вложенного объекта.

Существует два способа сопоставления имен, которые я знаю: атрибут ElasticType и свободный интерфейс NestedObject. Проблема здесь в том, что существует один тип, который представляет несколько типов вложенных объектов. Я мог бы создать некоторое построение типа времени выполнения, но я бы предпочел, чтобы избежать этого.

Можно ли использовать метод или свойство как имя/тип вложенного объекта? Или есть лучший подход к сопоставлению этого типа данных с ElasticSearch (надеюсь, через NEST)?

Спасибо! Erick

ИЗМЕНИТЬ

Я обновил определение сущности, чтобы отразить то, что я делаю (используя DynamicObject, чтобы заставить JsonSerializer делать то, что я хочу). Я хочу, чтобы различные словари имели разные сопоставления (разные стебли, анализаторы и т.д.). Если бы были подходящие типы, я мог бы использовать свободный синтаксис NEST для его настройки, но при использовании динамического типа для свободного API не существует. В конечном счете, я хочу смешивать свободный API со строкой на основе строк вместо типов. Это имеет смысл?

Ответы

Ответ 1

Если я правильно понимаю ваше намерение, объект Entity будет иметь в нем только вложенные объекты, не так ли?

Вы можете попытаться использовать динамическое сопоставление функции elasticsearch для объекта сущности. Я предполагаю, что Entity является корневым объектом.

curl -X POST localhost:9200/myindex/entity/_mapping
{"dynamic_templates": [
    {"nested_data_template": {
        "mapping": {
            "type": "nested" },
        "match_mapping_type": "object",
        "path_match": "*" }}]}

path_match: * и match_mapping_type: object означают, что для всех имен полей с объектом в качестве значения используется вложенное сопоставление типов.

Используя NEST и Fluent API, вы можете использовать следующий API. IntelliSense проведет вас как построить сопоставление выше.;)

descriptor.DynamicTemplates(DynamicTemplatesDescriptor<Entity>)

Каждый раз, когда появляется новое свойство, соответствующее этому шаблону, elasticsearch обновляет отображение на основе динамического сопоставления. Через некоторое время ваше сопоставление будет выглядеть следующим образом:

{
  "entity": {
    "mappings": {
      "entity": {
        "dynamic_templates": [
          {
            "nested_data_template": {
              "mapping": {
                "type": "nested"
              },
              "match_mapping_type": "object",
              "path_match": "*"
            }
          }
        ],
        "properties": {
          "test": {
            "type": "nested",
            "properties": {
              "test": {
                "type": "string"
              },
              "another_property": {
                "type": "string"
              }
            }
          },
          "test1": {
            "type": "nested",
            "properties": {
              "test": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}

Надеюсь, это поможет!