Фильтрация JMESPath со строкой - PullRequest
0 голосов
/ 24 февраля 2020

Я не могу найти решение, несмотря на множество исследований. Я застрял с функцией содержит. У меня есть 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"
      }]
}

Спасибо за вашу помощь

1 Ответ

0 голосов
/ 27 марта 2020

Вы не указали, с какой частью у вас возникли трудности. Я предполагаю, что это касается вложенных подопераций, поскольку это кажется мне самой сложной и наименее очевидной частью, но я постараюсь охватить все.

Вот мои предположения:

  • Ввод всегда состоит из объекта с полем data.
  • data поле всегда является объектом с полем operations.
  • operations is всегда массив.
  • Каждый член operations имеет четыре одинаковых поля: IDOperation, DateEcriture, Comment, sous_operations.
  • sous_operations всегда массив.
  • Каждый член sous_operations имеет три одинаковых поля: ID-sous-Operation (!), DateEcriture и Comment.
  • В частности, подоперации не являются вложенными глубиной более одного уровня.
  • Все поля, называемые Comment, являются строками.
  • Вы хотите найти как операции, так и подоперации, в которых есть "Счет-фактура" (без учета регистра) в их Comment поле.
  • Вы хотите вывести их, но не любые подоперации, которые они могут иметь.
  • Вы хотите переименовать ID-sous-Operation в IDOperation.

Я думаю, что это делает то, что вы хотите:

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

Сначала мы заменяем каждую операцию массивом из двух членов. Первый член - это массив из одного элемента, содержащий поля операции, но не ее подоперации. Второй член - это массив всех подопераций операции. (На этом этапе мы также переименовываем поле идентификатора подоперации.)

Итак, теперь у нас есть операции в виде массива (двухэлементных) массивов массивов упрощенных операций. Мы дважды используем оператор 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
    }
  ]
}
...