【问题标题】:Elasticsearch index array of made up of another class由另一个类组成的 Elasticsearch 索引数组
【发布时间】:2015-03-30 13:50:43
【问题描述】:

我有一个类,我想使用 Scala 客户端 elastic4s 开始对 ElasticSearch 进行索引。我扩展了 DocumentMap 以允许我插入文档。 String、Int 等简单值正在工作,但我似乎无法正确映射另一个类的列表。

文档看起来类似于这样:

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
  )
}

它将在 elasticsearch 中很好地映射 Id 字段,但是当将文档插入到 elasticsearch 中时,我得到一个看起来类似于此的不正确值:

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

显然这是错误的,一旦将其插入到 elasticsearch 中,我期待与此 JSON 结构类似的东西,例如:

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

有谁知道在使用 elastic4s 索引数据时映射复杂类型数组的方法?

【问题讨论】:

    标签: scala elasticsearch elastic4s


    【解决方案1】:

    Elastic4s 或 java 客户端(当前)不够聪明,无法确定您有一个嵌套的序列或数组,但如果它是一个嵌套的 java 映射,它就可以工作(从 Scala 的角度来看仍然有点垃圾)。

    我认为最好的办法是使用 1.4.13 中添加的新 Indexable 类型类

    所以,给定

    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 的实际应用

    【讨论】:

    • 谢谢。可惜它不支持开箱即用。不过我会尝试一下,因为它似乎给了我控制数据的最佳方式。
    • 很容易添加一个 JsonIndexable 来为你做一个辅助特性,可以添加它并 PR 吗?
    • 非常感谢。如果我让 JsonIndexable.还是我误解了 JsonIndexable 的作用?
    • 是的,它会检测到所有内容,因为它将利用 Jacksons 对创建嵌套 json 的支持。
    • 非常感谢@monkjack。所以它实际上会向elasticsearch发出一个索引请求,在json中看起来像这样:{ "Id": "some_string_id", "Things": [ {"UserName"; "some_user_string", "Comment": "some_comment_string", "Time": "2015-03-31"}, {"UserName"; "some_user_string_b", "Comment": "some_comment_string_b", "Time": "2015-03-31"} ] }
    【解决方案2】:

    首先你需要在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}
    

    【讨论】:

    • 干杯 @mhmtnlr 我无法通过 elastic4s 创建索引,而是在整个应用程序的其他位置创建索引。是否必须通过elastic4s才能让客户拿起它?此外,创建的索引将是示例中的 ThingsThatHappened 索引。 AThings 将是 ThingsThatHappened 索引中的一个数组字段。希望这是有道理的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-20
    • 1970-01-01
    • 2023-01-13
    • 2021-12-08
    • 2016-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多