Как мне сериализовать свойства типа JToken или JObject в Elasticsearch NEST? - PullRequest
0 голосов
/ 30 апреля 2018

Я представляю Elasticsearch в проекте C # API. Я хотел бы использовать существующие модели API в качестве поисковых документов, многие из которых позволяют добавлять пользовательские точки данных. Они реализованы с использованием типа JObject из Json.NET. Например:

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public JObject ExtraProps { get; set; }
}

Это позволяет пользователям отправлять тела запросов JSON следующим образом, что прекрасно работает:

{
   "Id": 123,
   "Name": "Thing",
   "ExtraProps": {
      "Color": "red",
      "Size": "large"
   }
}

Однако, если я использую это как тип документа в NEST, эти дополнительные свойства как-то теряют свои значения, сериализуя как:

{
   "Id": 123,
   "Name": "Thing",
   "ExtraProps": {
      "Color": [],
      "Size": []
   }
}

Добавление атрибута [Nest.Object] к ExtraProps не изменило поведение. Насколько я понимаю, NEST использует Json.NET для себя, поэтому я не ожидаю, что у него будут проблемы с типами Json.NET. Есть ли относительно простое исправление для этого?

Вот несколько вариантов, которые я взвешиваю:

  1. Использовать настраиваемую сериализацию . Я пошел по этому пути, мне стало гораздо сложнее, чем должно быть, и я так и не заработал.

  2. Карта JObject с Dictionary<string, object> с. Я проверил это работает, но если есть вложенные объекты (которые могут быть), мне нужно улучшить его с помощью рекурсии. И, в идеале, я бы хотел, чтобы это работало с более общим типом JToken . Это вариант, к которому я склоняюсь, но, опять же, он кажется более сложным, чем должен быть.

  3. Используйте «Низкоуровневый» клиент или даже необработанные HTTP-вызовы. По общему признанию я не исследовал это, но если это действительно проще / чище, чем альтернативы, я открыт для этого.

  4. Сообщить об ошибке. Я, вероятно, сделаю это независимо. У меня есть предположение, что это должно работать с JObject или любым JToken из коробки, если только по какой-то причине это не является предполагаемым поведением.

1 Ответ

0 голосов
/ 01 мая 2018

Это ожидаемое поведение с NEST 6.x.

NEST использует Json.NET для сериализации. Однако в NEST 6.x эта зависимость была встроена в сборку NEST

  • IL-объединение всех типов Json.NET в сборку NEST
  • переименование типов внутри Newtonsoft.Json в Nest.Json
  • маркировка всех типов internal

В блоге есть более подробная информация , объясняющая мотивы этого изменения.

Когда дело доходит до обработки типов Json.NET, таких как Newtonsoft.Json.Linq.JObject, Json.NET имеет специальную обработку для этих типов для сериализации / десериализации. В NEST 6.x интернализованный Json.NET не знает, как специально обрабатывать Newtonsoft.Json.Linq.JObject, потому что все типы во внутреннем Json.NET были переименованы в пространство имен Nest.Json.

Для поддержки типов Json.NET необходимо подключить сериализатор, который использует Json.NET для сериализации ваших документов. NEST.JsonNetSerializer пакет nuget был создан, чтобы помочь с этим. Просто добавьте ссылку на NEST.JsonNetSerializer в ваш проект, затем подключите сериализатор следующим образом

// choose the appropriate IConnectionPool for your use case
var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var connectionSettings =
    new ConnectionSettings(pool, JsonNetSerializer.Default);
var client = new ElasticClient(connectionSettings);

При этом месте документы со свойствами JObject будут сериализованы, как и ожидалось.

...