как хранить вложенные поля в elasticsearch

Я использую клиент REST высокого уровня Java. Вот ссылка на его документацию

Я создал клиент.

trait HighLevelRestClient {

  def elasticSearchClient(): RestHighLevelClient = {
   new RestHighLevelClient(
      RestClient.builder(
        new HttpHost("localhost", ElasticSearchPort, "http")))
  }
}

При индексировании данных вложенные поля сохраняются как String. Следующий код объясняет, как создается индекс:

val indexRequest = new IndexRequest("my-index", "test-type").source(
  "person", person,
  "date", DateTime.now()
)

где person - это класс case, представленный как:

Person(personId: String, name: String, address: Address) 

и Address сам по себе является классом case, представленным как:

Address(city: String, zip: Int)

Мое приложение требует, чтобы человек сохранялся как пара ключ-значение, чтобы его поля были доступны для поиска. Но когда я использую приведенный выше код, он сохраняется как String.

{
"person" : "Person(my-id, my-name, Address(my-city, zip-value))",
"date" :  "2017-12-12"
} 

и требуемая структура:

{
"person" : {
    "personId" : "my-id",
    "name" : "person-name",
    "address": {
      "city" : "city-name",
      "zip" : 12345
          }
     },
"date" : "2017-12-12"
}

Надеюсь, я хорошо сформулировал вопрос. Любая помощь будет оценена по достоинству. Спасибо!


person Shivangi Gupta    schedule 12.12.2017    source источник


Ответы (1)


Вы почти там. Для достижения цели вам необходимо:

  1. Сериализировать объект в JSON на вашей стороне
  2. Укажите тип содержимого запроса

На самом деле это описано на странице Index API.

Удобная библиотека для сериализации классов случаев в JSON, например, json4s (вы можете увидеть некоторые примеры сериализации здесь).

Ваш код может выглядеть следующим образом:

import org.apache.http.HttpHost
import org.elasticsearch.action.index.IndexRequest
import org.elasticsearch.client.{RestClient, RestHighLevelClient}
import org.elasticsearch.common.xcontent.XContentType
import org.joda.time.DateTime
import org.json4s.NoTypeHints
import org.json4s.jackson.Serialization
import org.json4s.jackson.Serialization.write

case class Address(city: String, zip: Int)

case class Person(personId: String, name: String, address: Address)

case class Doc(person: Person, date: String)

object HighClient {
  def main(args: Array[String]): Unit = {
    val client = new RestHighLevelClient(
      RestClient.builder(
        new HttpHost("localhost", 9206, "http")))

    implicit val formats = Serialization.formats(NoTypeHints)

    val doc = Doc(
      Person("blah1", "Peter Parker", Address("New-York", 33755)),
      DateTime.now().toString
    )

    val indexRequest = new IndexRequest("my-index", "test-type").source(
      write(doc), XContentType.JSON
    )

    client.index(indexRequest)

    client.close()
  }
}

Обратите внимание, что в этом случае:

new IndexRequest("my-index", "test-type").source(
  write(doc), XContentType.JSON
)

эта функция будет использоваться: public IndexRequest source(String source, XContentType xContentType)

Хотя в вашем случае:

new IndexRequest("my-index", "test-type").source(
  "person", person,
  "date", DateTime.now()
)

он вызовет public IndexRequest source(Object... source).

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

person Nikolay Vasiliev    schedule 13.12.2017