所以这是一个问题,我甚至不知道从哪里开始,所以即使是一个指向正确方向的指针也不错。在
所以我得到的数据是这样的:
data = {
"agg": {
"agg1": [
{
"keyWeWant": "*-20.0",
"asdf": 0,
"asdf": 20,
"asdf": 14,
"some_nested_agg": [
{
"keyWeWant2": 20,
"to": 25,
"doc_count": 4,
"some_nested_agg2": {
"count": 7,
"min": 2,
"max": 5,
"keyWeWant3": 2.857142857142857,
"sum": 20
}
},
{
"keyWeWant2": 25,
"to": 30,
"doc_count": 10,
"some_nested_agg2": {
"count": 16,
"min": 2,
"max": 10,
"keyWeWant3": 6.375,
"sum": 102
}
}
]
},
{
...
},
{
...
},
...
]
}
}
现在从这个例子来看,“agg”中有N个“agg1”结果,每个“agg1”结果中都有一个“keyWeWant”。每个“agg1”结果也有一个“some_nested_agg”结果列表,每个结果都包含一个“keyWeWant2”。每个“keyWeWant2”值都与层次结构中某个位置的单个“keyWeWant”值关联。类似地,每个“keyWeWant2”也包含“some_nested_agg2”的一组结果(这次不是一个列表,而是一个映射)。每个结果集都包含一个“keyWeWant3”。在
现在,我想在保持“keyWeWant”、“keyWeWant2”和“keyWeWant3”之间的关联的同时,将这个结构展平,得到如下结果:
我希望函数看起来像:
^{pr2}$这是一个只有深度3的例子,但是可能有任意深度,有些嵌套值是列表,有些是数组/列表。在
我想做的是编写一个函数来接收我想要的键以及在哪里找到它们,然后获取这些键并反规范化。在
看起来像:
function_name(data_map, {
"keyWeWant" : ['agg', 'agg1'],
"keyWeWant2" : ['agg', 'agg1', 'some_nested_agg'],
"keyWeWant" : ['agg', 'agg1', 'some_nested_agg', 'some_nested_agg2']
})
有什么想法吗?我熟悉Java、Clojure、javascript和Python,只是想找到一种相对简单的方法来解决这个问题。在
也许有更好的方法来解决这个特定的问题(使用一些ElasticSearch库或其他东西),但是这里有一个Clojure的解决方案,使用您请求的输入和输出数据格式。在
我把这个测试数据放在一个名为
data.json
的文件中:然后,Cheshire JSON library将数据解析为Clojure数据结构:
^{pr2}$接下来,要获取的路径定义如下:
上面的
data_map
没有“:”,单引号改为双引号,最后一个“keyWeWant”改为“keyWeWant3”。在下面的} 的语义,只有这样它才能在带有向量的映射上工作,并返回所有值而不是一个值。
当给
find-nested
具有Clojure的^{find-nested
一个搜索向量时,它会在一个嵌套映射中找到所有值,其中一些值可以由一个带有映射列表的向量组成。矢量中的每个贴图都会被检查。在find-nested
查找搜索路径的值:如果指向“keyWeWant”的所有路径都映射到
my-data
上,则这些是tree
的切片:您所要求的结构(所有路径到达的最终结果)可以从
function-name
中的tree
获得,如下所示:如果} 后退一步。我认为对于更深层次的嵌套结构也会有效果——如果下一个切片的大小始终是前一个切片的两倍,或者应该是相同的大小,但我还没有对其进行测试。在
results
大于特定的片,则results
使用^{{{cd7>请求的{cd7>}将导致
/编辑 我知道你在寻找一个相对简单的解决方案,但事实并非如此。:-)可能有一个库中没有它。我很乐意知道如何简化它。在
这里有一个JavaScript(ES6)函数可以使用:
function flatten(data, keys) { var key = keys[0]; if (key in data) keys = keys.slice(1); var res = keys.length && Object.keys(data) .map( key => data[key] ) .filter( val => Object(val) === val ) .reduce( (res, val) => res.concat(flatten(val, keys)), []); return !(key in data) ? res : (res || [{}]).map ( obj => Object.assign(obj, { [key]: data[key] }) ); } // Sample data var data = { "agg": { "agg1": [ { "keyWeWant": "*-20.0", "asdf": 0, "asdf": 20, "asdf": 14, "some_nested_agg": [ { "keyWeWant2": 20, "to": 25, "doc_count": 4, "some_nested_agg2": { "count": 7, "min": 2, "max": 5, "keyWeWant3": 2.857142857142857, "sum": 20 } }, { "keyWeWant2": 25, "to": 30, "doc_count": 10, "some_nested_agg2": { "count": 16, "min": 2, "max": 10, "keyWeWant3": 6.375, "sum": 102 } } ] }, ] } }; // Flatten it by array of keys var res = flatten(data, ['keyWeWant', 'keyWeWant2', 'keyWeWant3']); // Output result console.log(res);
;使用替代eh3路径>
如注释中所述,上面的代码不使用路径信息;它只查看所有数组。如果要查找的密钥也出现在应忽略的路径中,则可能会出现问题。在
以下替代方法将使用路径信息,该信息应作为子数组的数组传递,每个子数组首先列出路径键,最后一个元素是要保留的值键: