我想将一些JSON(带有inner_hits的Elasticsearch搜索结果)解析为一个平面记录,但是记录的某些字段应该来自列表中的一个项目,该列表又位于一个嵌套对象中:
{
"_index": "test",
"_type": "doc",
"_id": "AUG.02.013.1320.02630.0",
"_score": null,
"_routing": "1",
"_source": {
"child_mgrpid": "1.1",
"child_varia": "blabla",
"type": "child",
"my_join_field": {
"name": "child",
"parent": "AUG.02.013.1320"
},
"@version": "1",
"@timestamp": "2020-01-12T16:45:11.302Z",
},
"inner_hits": {
"prnt": {
"hits": {
"total": 1,
"max_score": null,
"hits": [
{
"_index": "test",
"_type": "doc",
"_id": "AUG.02.013.1320",
"_score": null,
"_routing": "1",
"_source": {
"pt_archiv": "",
"pt_id": "AUG.02.013.1320",
"pt_titel": "",
"pt_l_id": "AUG.02.013",
"pt_l_name": "Johann Christoph von Freyberg-Eisenberg"
"pt_t_id": "AUG",
"pt_t_kurzform": "AUG",
"type": "parent",
"my_join_field": {
"name": "parent"
},
"@version": "1",
"@timestamp": "2020-01-12T16:45:08.470Z",
},
"sort": [
"AUG"
]
}
]
}
}
}
}
(实际上,数据字段比示例中的要多,因此我不能使用Decoder.mapX
函数。)我可以肯定地知道Decoder.mapX
列表中始终只有一个条目/父项,我想将其inner_hits.prnt.hits.hits
字段与“ main”对象中的字段一起放平到记录的类型定义中,如下所示:
_source
这里是我到目前为止拥有的解码器:
type alias Child =
{ grp_id : String
, varia : String
, pt_archive : String
, pt_id : String
, pt_title : String
, pt_l_id : String
, pt_l_name : String
, pt_t_id : String
, pt_t_shortLabel : String
}
([type alias Parent =
{ pt_archive : String
, pt_id : String
, pt_title : String
, pt_l_id : String
, pt_l_name : String
, pt_t_id : String
, pt_t_shortLabel : String
}
childHitDecoder : Decoder Child
childHitDecoder =
Json.Decode.succeed Child
|> Json.Decode.Pipeline.requiredAt [ "_source", "child_mgrp_id" ] Json.Decode.string
|> Json.Decode.Pipeline.requiredAt [ "_source", "child_varia" ] Json.Decode.string
|> Json.Decode.Pipeline.custom (Json.Decode.at [ "inner_hits", "prnt", "hits", "hits" ] (firstElementDecoder parentInnerHitDecoder) )
firstElementDecoder : Json.Decode.Decoder a -> Json.Decode.Decoder a
firstElementDecoder baseDecoder =
Json.Decode.list baseDecoder
|> Json.Decode.map List.head
|> Json.Decode.andThen (Maybe.map Json.Decode.succeed >> Maybe.withDefault (Json.Decode.fail "Empty list"))
parentInnerHitDecoder : Decoder Parent
parentInnerHitDecoder =
Json.Decode.succeed Parent
|> Json.Decode.Pipeline.requiredAt [ "_source", "archiv" ] Json.Decode.string
|> Json.Decode.Pipeline.requiredAt [ "_source", "id" ] Json.Decode.string
|> Json.Decode.Pipeline.requiredAt [ "_source", "titel" ] Json.Decode.string
|> Json.Decode.Pipeline.requiredAt [ "_source", "lah_id" ] Json.Decode.string
|> Json.Decode.Pipeline.requiredAt [ "_source", "lah_name" ] Json.Decode.string
|> Json.Decode.Pipeline.requiredAt [ "_source", "ter_id" ] Json.Decode.string
|> Json.Decode.Pipeline.requiredAt [ "_source", "ter_kurzform" ] Json.Decode.string
来自firstElementDecoder
,我想用它来取消列出一个inner_hits列表项。]
[使用这样的设置,我的Elm: Decode a JSON array with a single element into a string的最后一行给出了错误:
childHitDecoder
我已经成功地使用This function cannot handle the argument sent through the (|>) pipe:
482| Json.Decode.succeed Child
483| |> Json.Decode.Pipeline.requiredAt [ "_source", "child_mgrp_id" ] Json.Decode.string
484| |> Json.Decode.Pipeline.requiredAt [ "_source", "child_varia" ] Json.Decode.string
485| |> Json.Decode.Pipeline.custom (Json.Decode.at [ "inner_hits", "prnt", "hits", "hits" ] (firstElementDecoder parentInnerHitDecoder) )
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The argument is:
Decoder
(
String
-> String
-> String
-> String
-> String
-> String
-> String
-> Child
)
But (|>) is piping it to a function that expects:
Decoder (Parent -> b)
Hint: It looks like it takes too many arguments. I see 6 extra.
来将嵌套的JSON对象解码为其他地方的扁平elm记录,但是显然,将其与此处的除名结合起来已经超出了我。
这使我困惑了好几天,我也尝试过将字段捆绑与Decode.Pipeline.custom
组合在一起,但是也失败了。我对Decode.Pipeline.custom
或Decode.map
的理解不够,无法在这里找到帮助,我将非常感谢您的帮助。
使用上面列出的json对象,以下方法应该起作用: