Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/scala/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala elastic4s:如何将文档id自动读入案例类实例?_Scala_<img Src="//i.stack.imgur.com/RUiNP.png" Height="16" Width="18" Alt="" Class="sponsor Tag Img">elasticsearch_Spray Json_Elastic4s - Fatal编程技术网 elasticsearch,spray-json,elastic4s,Scala,elasticsearch,Spray Json,Elastic4s" /> elasticsearch,spray-json,elastic4s,Scala,elasticsearch,Spray Json,Elastic4s" />

Scala elastic4s:如何将文档id自动读入案例类实例?

Scala elastic4s:如何将文档id自动读入案例类实例?,scala,elasticsearch,spray-json,elastic4s,Scala,elasticsearch,Spray Json,Elastic4s,将elastic4s 7.12.1与spray json 1.3.6(和scala2.13.5)一起使用: 是否有办法将Elasticsearch文档的\u id读入字段,例如id,属于case类实例,仅使用隐式spray jsonRootJsonFormat,i。E无需为elastic4s编写自定义的点击阅读器,如果是,怎么做? 编写文档也是如此:是否有一种方法可以插入一个案例类的实例,而不必使用前面提到的RootJsonFormat将其序列化(使其成为ES中\u source的一部分)到id

将elastic4s 7.12.1与
spray json 1.3.6
(和scala
2.13.5
)一起使用:
是否有办法将Elasticsearch文档的
\u id
读入字段,例如
id
,属于
case类
实例,
仅使用隐式
spray json
RootJsonFormat
,i。E无需为elastic4s编写自定义的点击阅读器,如果是,怎么做?
编写文档也是如此:是否有一种方法可以插入一个
案例类的实例,而不必使用前面提到的
RootJsonFormat
将其序列化(使其成为ES中
\u source
的一部分)到
id
字段。E没有编写自定义的可索引的

根据
elastic4s
文档,使用
jackson
应该可以做到这一点,我希望避免这种情况,因为它总是会出现许多关键的安全问题

考虑这个case类,它应该被索引到ES中:

case类Foo(id:String,name:String)
使用
spray-json
,我只需要定义
RootJsonFormat

implicit val fooJsonFormat:RootJsonFormat[Foo]=jsonFormat2(Foo)
并且可以使用
elastic4s
这种方式来索引和搜索
Foo
s:

val someFoo=Foo(“应该覆盖的ID”、“someName”)
client.execute{
indexInto(“foos”).doc(someFoo)
}
val结果:响应[SearchResponse]=client.execute{
搜索(“foos”).query{
boolQuery()。必须{
匹配查询(“名称”、“someName”)
}
}
}.等待
结果匹配{
case RequestSuccess(u,u,u,result)=>result.to[Foo].foreach(println)
case RequestFailure(u,u,u,error)=>println(error.toString)
}
然而,这种方法存在一些主要问题:

  • 我需要在创建
    Foo
    时提供
    id
    ,而实际上我希望ES在索引文档时为我生成
    \u id
    。当然,这主要是由于使用了
    案例类
  • 加载
    Foo
    文档时,其
    id
    字段包含我为其编制索引时使用的(无意义的)伪值,而不是存储在ES节点中的实际
    \u id
为了解决这些问题(第一个只是部分),我当然可以编写自己的
Indexable
HitReader
,如下所示:

隐式对象FooHitReader扩展HitReader[Foo]{
覆盖def读取(命中:命中):Try[Foo]=Try({
val source=hit.sourceAsMap
福(
id=hit.id,
名称=源(“名称”).toString
)
})
}
隐式对象FooIndexable扩展了可索引[Foo]{
重写def-json(t:Foo):字符串=
JsObject(
“name”->JsString(t.name),
).compactPrint
}
在一个小例子中,这看起来并不可怕,但我认为很明显,这种方法伸缩性很差,不提供类型安全,而且是重构的噩梦,因为字段的名称(例如,
“name”
)需要手动指定

底线:是否有更好的方法来实现类似于
spring data elasticsearch
的体验,或者
elastic4s
spray json
一起使用不适合此任务



编辑:另一种可能是从
Foo
中删除
id
字段,引入包装器
case类
,例如
fooResultRapper
,它通过
\u id
映射[String,Foo]
中存储
Foo
搜索结果,使用
RootJsonFormat[Foo]
HitReader[fooResultRapper]
\u源代码
转换为
Foo
,并通过
hit.id
存储。但这也不是很令人满意。

看看我提出的精彩解决方案(基本上就是我在编辑问题时提出的):
删除了我的域
案例类
id
字段(例如
Foo
),并引入了一个通用的
案例类
来包装结果,并强制使用
对象
来实现
elastic4s
读取特定
案例类

case类ESResultWrapper[T](id:String,result:T)
以及一个通用的
trait
,它包含在
ESResultWrapper
实例中包装
T
类型结果的实现:

trait ESResultWrapperHitReader[T]扩展了HitReader[ESResultWrapper[T]]{
def readInternal(hit:hit)(隐式读取器:HitReader[T]):Try[ESResultWrapper[T]]=Try({
ESResultWrapper(
id=hit.id,
结果=命中到[T]
)
})
}
现在,实际的“域”类剩下的就是使用特定的case类(也存在
RootJsonFormat
)扩展
ESResultWrapperHitReader[T]
trait
,并将
hit
委托给
hitInternal
,从而隐式地提供
HitReader[T]
通过
RootJsonFormat[T]

隐式对象FooResultWrapperHitReader扩展ESResultWrapperHitReader[Foo]{
覆盖def read(hit:hit):尝试[ESResultWrapper[Foo]]=readInternal(hit)
} 
用法非常简单(按照问题中的示例):

结果匹配{
case RequestSuccess(u,u,u,result)=>result.to[ESResultWrapper[Foo]].foreach(println)
case RequestFailure(u,u,u,error)=>println(error.toString)
}
导致e。g、 :
ESResultWrapper(-XMSQXkB-5ze1JvrVWup,Foo(“someFoo”))

最好的部分是:包装实现不会影响域类

我申请