труба в del (... | select (... | ...)) работает в v1.6, как получить тот же результат в v1.5? - PullRequest
0 голосов
/ 27 февраля 2019

Я пытаюсь удалить некоторые объекты на основе тегов в массиве.Я могу заставить его работать нормально на jqplay.org (v1.6), но есть ли способ получить тот же результат в v1.5?Я просто получаю сообщение об ошибке Invalid path expression with result

Цель состоит в том, чтобы вернуть JSON без двух верхних (content и data) уровней и со свойствами notes, если нетЭто types тег, начинающийся с 'x' или 'y' для этой заметки.

Вот рабочий пример v1.6: https://jqplay.org/s/AVpz_IkfJa

Также есть это: https://github.com/stedolan/jq/issues/1146 но я не знаю, как (или если это возможно) применить обходной путь для del() вместо path(), предполагая, что это та же самая основная проблема.

Инструкции JQ:

.content.data 
  | del(
  .hits[].doc.notes[] 
    | select
    ( .types 
      | any(startswith("x") or startswith("y")) 
      | not 
    )
  )

ввод JSON:

{ 
  "content": { "data": {
   "meta": "stuff",
   "hits": [
    { "doc": 
      {
        "id": "10",
        "notes": {
         "f1": {"name": "F1", "types": ["wwwa", "zzzb"] },
         "f2": {"name": "F2", "types": ["xxxa", "yyya"] }
       }
     },
     "score": "1"
   },
   { "doc": 
    {
      "id": "11",
      "notes": {
       "f1": {"name": "F1", "types": ["wwwa", "zzzb"] },
       "f3": {"name": "F3", "types": ["qzxb", "xxxb"] }
     }
   },
   "score": "2"
 } ] } } }  

Желаемый результат:

{
  "meta": "stuff",
  "hits": [
    {
      "doc": {
        "id": "10",
        "notes": {
          "f2": {"name": "F2", "types": ["xxxa", "yyya"] }
        }
      },
      "score": "1"
    },
    {
      "doc": {
        "id": "11",
        "notes": {
          "f3": {"name": "F3", "types": ["qzxb", "xxxb"] }
        }
      },
      "score": "2"
} ] }

Любые предложения с благодарностью.Я в значительной степени JQ новичок.Даже если в v1.5 это практически невозможно, по крайней мере, я не потеряю больше часов, пытаясь заставить его работать.

Ответы [ 2 ]

0 голосов
/ 02 марта 2019

Это всего лишь вариант решения, предложенного ОП.Он иллюстрирует, как сложное использование del может быть выражено более простым и надежным способом путем создания подходящей вспомогательной функции.

Соответствующая вспомогательная функция в данном случае реализует требование извлечения:

# Input: an object some keys of which are to be removed
def prune:
   to_entries
   | map( select( any(.value.types[]; test("^(x|y)")) ) )
   | from_entries ;

Теперь задачу можно выполнить с помощью однострочного:

.content.data | .hits |= map( .doc.notes |= prune )

Вызов

С помощью вышеуказанной jq-программы в program.jq, подходящий вызов jqбудет выглядеть так:

jq -f program.jq input.json
0 голосов
/ 28 февраля 2019

OP вернулся через несколько часов - я нашел кое-что, что, кажется, работает, все еще очень заинтересованный в любых комментариях / других способах взломать проблему / улучшения.

.content.data  
  | .hits[].doc.notes |= map (
    if ( .types | any(startswith("x") or startswith("y")))
      then .
      else empty
    end 
  )
...