根据路径展平/减少嵌套的JSON,在路径/层次结构中收集字段

时间:2018-11-16 00:39:06

标签: javascript elasticsearch

更新:11/18/18:我在本文的末尾添加了更多示例和说明。

我有嵌套的JSON结构,它是由Elasticsearch聚合产生的,看起来与此类似(为示例简化):

{
"some_field": "ignore",
"buckets": [
  {
    "key": "a",
    "buckets": [
      { "key": "foo", "name": "FOO" },
      { "key": "bar", "name": "BAR" }
    ]
  },
  {
    "key": "b",
    "buckets": [
      { "key": "boo", "name": "BOO" },
      { "key": "baa", "name": "BAA" }
    ]
  }
]
}

我想将其转换为

[ 
    {key: "a", name: "FOO"},
    {key: "a", name: "FOO"},
    {key: "b", name: "BOO"},
    {key: "b", name: "BAA"}
]

尽管对于任何特定情况这都是一个简单的问题,但我不想每次都“重新发明轮子”并为其编写代码。嵌套的级别可能会有所不同,我可能会选择的字段(沿着路径)也会有所不同。

以上是一些简化的示例。由于这些来自Elasticsearch响应,因此另一个示例可能是:

"aggregations": {
"boo": {
  "buckets": [
    {
      "key": "keyA",
      "foo": {
        "buckets": [
          {
            "key": "keyA.a",
            "bar": {
              "hits": {
                "hits": [{"_index": "indexA", "_id": "idA", "_source": {"name": "nameA"}}]
              }
            }
          }
        ]
      }
    },
    {
      "key": "keyB",
      "foo": {
        "buckets": [
          {
            "key": "keyA.a",
            "bar": {
              "hits": {
                "hits": [{"_index": "indexB", "_id": "idB", "_source": {"name": "nameB"}}]
              }
            }
          }
        ]
      }
    }
  ]
}

}

和我想要的结果,对于扁平化/拾取字段是

[
{"boo": "keyA", "foo": "keyA.a", "name": "nameA", "id": "idA"},
{"boo": "keyB", "foo": "keyA.a", "name": "name", "id": "idB"}
]

有人知道与JMESPath,JSONPath,lodash等相关的方法吗?使用JSONPath或JMESPath之类的东西,我可以轻松选择“叶子”值,但是我试图在层次结构中沿路径收集字段。

如前所述,我可以为每种情况编写代码,但是我想重用一个库并声明我的投影。

我想可以用jq做到这一点,但我需要它在浏览器中运行。

谢谢

1 个答案:

答案 0 :(得分:1)

Lodash在您的情况下很有用,可以在浏览器中使用。 您需要flapMapmap函数。

const _ = require('lodash');
var obj = {
  "some_field": "ignore",
  "buckets": [
    {
      "key": "a",
      "buckets": [
        { "key": "foo", "name": "FOO" },
        { "key": "bar", "name": "BAR" }
      ]
    },
    {
      "key": "b",
      "buckets": [
        { "key": "boo", "name": "BOO" },
        { "key": "baa", "name": "BAA" }
      ]
    }
  ]
};

var res = _.flatMap(obj.buckets, x => {
  return _.map(x.buckets, y => {
    y.key = x.key;
    return y;
  });
});

console.log(res);
//  Output:
//  [ { key: 'a', name: 'FOO' },
//    { key: 'a', name: 'BAR' },
//    { key: 'b', name: 'BOO' },
//    { key: 'b', name: 'BAA' }]