2015-03-30 3 views
0

У меня есть класс, который я хочу начать индексировать в ElasticSearch, используя эластичный клиент Scala. Я расширил DocumentMap, чтобы позволить мне вставлять документы. Простые значения, такие как String, Int и т. Д., Работают, но я не могу заставить список другого класса правильно отображать.Индексный массив Elasticsearch из другого класса

документы выглядят примерно так:

case class AThing(UserName: String, Comment: String, Time: String) 
extends DocumentMap { 
    override def map: Map[String, Any] = Map(
    "UserName" -> UserName, 
    "Comment" -> Comment, 
    "Time" -> Time 
) 
} 

case class ThingsThatHappened(Id: String, Things: Seq[AThing] = Nil) 
extends DocumentMap { 
    override def map: Map[String, Any] = Map(
    "Id" -> Id, 
    "Things" -> Things 
) 
} 

Он будет отображать поле Id штраф в elasticsearch, но затем я получаю неправильное значение, которое выглядит примерно так, когда документ вставляется в elasticsearch:

List(AThing(id_for_the_thing,user_name_a,typed_in_comment,2015-03-12)) 

Очевидно, что это не так, и я ожидал что-то родней этой структуры JSON, когда он был вставлен в elasticsearch, такие как:

"events" : [ 
    { 
    "UserName" :"user_name_a", 
    "Comment": "typed_in_comment", 
    "Time": "2015-03-12" 
    } 
] 

Кто-нибудь знает способ сопоставления массива сложных типов при индексировании данных с помощью elastic4s?

ответ

1

Elastic4s или клиент Java (в настоящее время) не достаточно умен, чтобы понять, что у вас есть вложенная последовательность или массив, но он будет работать, если это вложенное Java карта (еще немного мусора от Scala).

Я думаю, что лучше всего сделать, это использовать новый Неперетачиваемые класс типов, который был добавлен в 1.4.13

Таким образом, учитывая

case class AThing(UserName: String, Comment: String, Time: String) 

Затем создать класс типа и привести его в рамки

implicit object AThingIndexable extends Indexable[AThing] { 
    def json = ... create json here using Jackson or similar which will handle nested sequences properly 
} 

Тогда вы должны быть в состоянии сделать:

client.execute { index into "myIndex/AThings" source aThing } 

Это не совсем автоматическое использование DocumentMap, но дает вам больше контроля.

См модульного тестирования here с ним в действии

+0

спасибо. Жаль, что он не поддерживается из коробки. Я попробую хотя бы попробовать, поскольку он, похоже, дает мне лучший способ контролировать данные. – Darren

+0

Достаточно легко добавить JsonIndexable, который делает это для вас как вспомогательный признак, может добавить это и PR? – monkjack

+0

спасибо было бы здорово. Подойдет ли это ко всему этому, чтобы обнаружить внутренние вложенные типы, если я создам JsonIndexable.Или я не понимаю, что собирается сделать JsonIndexable? – Darren

0

Прежде всего, вам нужно создать индекс в elastic4s. Я полагаю, вы сделали это.

client.execute { 
    create index "myIndex" mappings (
    "AThings" as(
     "UserName" typed StringType, 
     "Comemnt" typed StringType, 
     "Time" typed StringType, 
    ) 
    ) 
} 

Если вы создадите этот индекс, то вы можете сразу ввести класс case.

val aThings = AThings("username","comment","time") 
client.execute {index into "myIndex/AThings" doc aThings} 
+0

приветствий @mhmtnlr Я не могу создать индекс с помощью elastic4s вместо него создается в другом месте в пределах всего приложения. Должно ли это быть сделано через elastic4s для клиента, чтобы забрать его? Также индекс, который был создан, будет индексировать ThingsThatHappened в этом примере. AThings будет полем массива в индексе ThingsThatHappened. Надеюсь, это имеет смысл. – Darren

Смежные вопросы