根据子数组信息使用 JSONPath 过滤数组

Filter array with JSONPath depending on subarray information

我有 JSON 和 https://www.w3resource.com/JSON/JSONPath-with-JavaScript.php 中一样的电影数组,但有额外的演员数组和隐式类型信息(数据库、电影)。

我创建了这个 JSFiddle:https://jsfiddle.net/prorep/7nhvb6sg/15/

我尝试为特定演员参与的所有电影过滤此数组。 当我尝试这样的事情时:

jsonPath(json, "$.[actors[?(@.id==2)]]")

我只得到了演员的数组两次,但没有得到完整的电影。所以我认为问题可能出在定义根元素上——但同样不起作用的是 $.*[...], $.[*][...], $[*.[...]], ...

我尝试得到的结果:

    [{
     "name": "30 Minutes or Less",
     "genre": "adventure",
     "director": "Ruben Fleischer",
     "Facebook_like": 114,
     "actors": [{
       "id": 2,
       "name": "Jesse Eisenberg"
     }]
   },
   {
     "name": "The Social Network",
     "genre": "Biography",
     "director": "David Fincher",
     "Facebook_like": 0,
     "actors": [{
       "id": 2,
       "name": "Jesse Eisenberg"
     }]
   }
 ]

好问题。您在示例中使用了 Goessner 的参考 JSONPath 实现(提出 JSONPath 的人)以及教程页面上的实时测试(页面上的下载 link 似乎 link 到略有不同的版本)。您提出的查询实际上不受支持,它只能部分工作。评估的路径与匹配所有 id 值 2 的递归下降相同:$..[?(@.id==2)],参与者部分被忽略。您可以将此称为错误、不支持的语法或不完整的实现。问题是,JSONPath(还)没有标准化,不同的实现有不同的特性,或多或少微妙的路径定义。

虽然这在参考 (JS) 实现中不起作用,但我们仍然可以找到可以按要求查询数据的其他实现。

在 Java 脚本世界中,我们可以使用 JsonPath-Plus(这可能是当今功能最丰富的实现之一)使用扩展语法来获取父 $..[?(@.id ==2)]^在末尾使用 ^ 和解析器标志来获取父项的父项,即。具有演员数组

的 属性
JSONPath({json: json,
          path: "$..[?(@.id ==2)]^",
          wrap: false,
          resultType: 'parent'});

如下所示:

.as-console-wrapper { max-height: 100% !important; top: 0; }
<script type="module">

import {JSONPath} from 'https://cdn.jsdelivr.net/npm/jsonpath-plus@4.0.0/dist/index-es.js';

 const json = [{
     "name": "The Change-Up",
     "genre": "comedy",
     "director": "David Dobkin",
     "Facebook_like": 252,
     "actors": [{
       "id": 1,
       "name": "Ryan Reynolds"
     }]
   },
   {
     "name": "Rise of the Planet of the Apes",
     "genre": "SciFi",
     "director": "Rupert Wyatt",
     "Facebook_like": 472,
     "actors": []
   },
   {
     "name": "30 Minutes or Less",
     "genre": "adventure",
     "director": "Ruben Fleischer",
     "Facebook_like": 114,
     "actors": [{
       "id": 2,
       "name": "Jesse Eisenberg"
     }]
   },
   {
     "name": "Final Destination 5",
     "genre": "Horror",
     "director": "Steven Quale",
     "Facebook_like": 241,
     "actors": []
   },
   {
     "name": "The Social Network",
     "genre": "Biography",
     "director": "David Fincher",
     "Facebook_like": 0,
     "actors": [{
       "id": 2,
       "name": "Jesse Eisenberg"
     }]
   }
 ];

 console.log(JSONPath({
        json: json,
        path: "$..[?(@.id ==2)]^",
        wrap: false,
        resultType: 'parent'
}));

</script>

另一个可以查询请求元素的非常强大的 JSONPath 实现是 Jayway's implementation for Java。同样,以下语义合理的路径(对我而言)不适用于许多其他实现:

$.[?(@.actors[*].id ==[2])]

您可以在线尝试查询 here 并进一步探索其他实现之间的差异。

实际情况是,您需要参考具体实现的文档才能在您的项目中很好地使用 JSONPath。