Json.Decode:提取列表项并将其展平/合并到记录中

问题描述 投票:1回答:1

我想将一些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.customDecode.map的理解不够,无法在这里找到帮助,我将非常感谢您的帮助。

elm
1个回答
0
投票

使用上面列出的json对象,以下方法应该起作用:

© www.soinside.com 2019 - 2024. All rights reserved.