首页 > 解决方案 > 用字符串过滤 JMESPath

问题描述

尽管进行了大量研究,但我找不到解决方案。我坚持使用 contains 功能。我有这个 Json 文件:

    {
  "from": "Api",
  "success": true,
  "message": "",
  "errors": [],
  "data": {
    "operations": [
      {
        "IDOperation": 100,
        "DateEcriture": "2019-01-02",
        "Comment": "Invoice Nh5 numero 152",
        "sous_operations": []
      },
      {
        "IDOperation": 101,
        "DateEcriture": "2019-01-02",
        "Comment": "one other thing",
        "sous_operations": []
      },
      {
        "IDOperation":102,
        "DateEcriture": "2019-01-02",
        "Comment": "an other thing",
        "sous_operations": [{"ID-sous-Operation": 103,
                           "DateEcriture": "2019-01-02",
                           "Comment": "Invoice Nh15 numero 341"}]
      }]
   } 
}

我想过滤在“评论”字段中包含“发票”一词的对象以获得以下信息:

{"operations": [
      {
        "IDOperation": 100,
        "DateEcriture": "2019-01-02",
        "Comment": "Invoice Nh5 numero 152"
      },
      {
        "IDOperation": 103,
        "DateEcriture": "2019-01-02",
        "Comment": "Invoice Nh15 numero 341"
      }]
}

谢谢你的帮助

标签: jsonsearchsubstringcontainsjmespath

解决方案


您还没有说明您遇到困难的部分。我猜它正在处理嵌套的子操作,因为这对我来说似乎是最难和最不明显的部分,但我会尝试涵盖所有内容。

以下是我的假设:

  • 输入总是由一个带有字段的对象组成data
  • datafield 始终是带有 field 的对象operations
  • operations始终是一个数组。
  • 的每个成员operations都有相同的四个字段:IDOperation, DateEcriture, Comment, sous_operations
  • sous_operations始终是一个数组。
  • 的每个成员都sous_operations具有相同的三个字段:( ID-sous-Operation!)DateEcritureComment.
  • 特别是,子操作的嵌套深度不超过一层。
  • 所有调用的字段Comment都是字符串。
  • Comment您想查找在其字段中具有“发票”(不区分大小写)的操作和子操作。
  • 您想输出它们,而不是它们可能具有的任何子操作。
  • 您想重命名ID-sous-OperationIDOperation.
  • 输出应包含一个包含单个字段的对象,该字段operations是选定和转换操作的数组。

我认为这可以满足您的要求:

{
  operations:
    data.operations|
    map(
      &[
        [
          {
            IDOperation:IDOperation,
            DateEcriture:DateEcriture,
            Comment:Comment            
          }
        ],
        map(
          &{
            IDOperation:"ID-sous-Operation",
            DateEcriture:DateEcriture,
            Comment:Comment
          },
          sous_operations
        )
      ],
      @
    )|
    [][]|
    [?contains(Comment,`"Invoice"`)]
}

首先,我们用一个二元数组替换每个操作。第一个成员是一个包含操作字段但不包含其子操作的单元素数组。第二个成员是所有操作的子操作的数组。(此时我们也重命名了子操作 ID 字段。)

所以现在我们将操作作为简化操作数组的(两个元素)数组。我们使用 flatten 运算符两次来获得一个简单的单级数组。最后,我们简单地使用 contains 方法对其进行过滤。

这是输出:

$ jp --filename input1.json --expr-file filter.jmespath
{
  "operations": [
    {
      "Comment": "Invoice Nh5 numero 152",
      "DateEcriture": "2019-01-02",
      "IDOperation": 100
    },
    {
      "Comment": "Invoice Nh15 numero 341",
      "DateEcriture": "2019-01-02",
      "IDOperation": 103
    }
  ]
}

推荐阅读