Свести / уменьшить вложенный JSON на основе путей, собирая поля в пути / иерархии - PullRequest
0 голосов
/ 16 ноября 2018

ОБНОВЛЕНИЕ: 18/11/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 голосов
/ 16 ноября 2018

Lodash полезен в вашем случае и может быть использован в браузере. flapMap и map Функции - это то, что вам нужно.

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' }]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...