Используйте переменную диапазона jq для подачи в новый фильтр jq - PullRequest
1 голос
/ 24 апреля 2019

У меня есть JSON, который выглядит следующим образом:

{
    "vertices": [
        {
         "id": 71597,
          "ns": "ca",
          "alias": "polarized"
        },
        {
          "id": 129748,
          "ns": "av",
          "name": "Polarized"
        },
        {
          "id": 129898,
          "ns": "av",
          "name": "False"
        }
    ],
    "edgeGroups": {
        "hasAttributeValue": [
            [
              0,
              1
            ],
            [
              0,
              2
            ]
        ]
    }
}

Различные записи в .vertices связаны индексом массива.Таким образом, в этом случае первая вершина (id: 71597 - с индексом массива 0) имеет значения атрибутов 129748 и 129898 (с индексами массива 1 и два соответственно).

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

.vertices | range(0;length) as $i | select(.[$i].alias=="polarized" and .[$i].ns=="ca") | $i

Возвращает значение $ i, равное 0, поскольку объект с псевдонимом «поляризованный» является первым элементом вмассив.Вы можете попробовать это здесь на jq play:

https://jqplay.org/s/DsHYi7ixyn

Теперь я хочу использовать это значение $ i в другом фильтре, поэтому вместо вывода 0он выводит что-то вроде результата этого:

.edgeGroups.hasAttributeValue[] | select(.[0] == 0)

Я пытался использовать оператор pipe, как это, но он просто дает мне ошибку:

.vertices | range(0;length) as $i | select(.[$i].alias=="polarized" and .[$i].ns=="ca") | .edgeGroups.hasAttributeValue[] | select(.[0] == $i)

Если бы я мог понять, как использовать $ i в цепочечном фильтре, я думаю, что мог бы решить мою главную цель - объединить несколько фильтров, чтобы я мог собрать все элементы, связанные с 71597объект - т.е.

        {
          "id": 129748,
          "ns": "av",
          "name": "Polarized"
        },
        {
          "id": 129898,
          "ns": "av",
          "name": "False"
        }

Спасибо за любую помощь заранее!

Ответы [ 2 ]

3 голосов
/ 24 апреля 2019

Ваш фильтр jq может быть исправлен парой скобок:

(.vertices
 | range(0;length) as $i
 | select(.[$i].alias=="polarized" and .[$i].ns=="ca")
 | $i) as $i
| .edgeGroups.hasAttributeValue[]
| select(.[0] == $i)
0 голосов
/ 25 апреля 2019

позвольте мне предложить альтернативное решение по вашему запросу - Unix-инструмент Walk-Path для JSON: jtc. В jtc вы «кодируете» свой запрос в сам путь обхода, поэтому конечная цель будет выглядеть следующим образом:

bash $ <file.json jtc -w'[vertices][alias]:<polarized>[-1][ns]:<ca>[-1]<idx>k [^0][edgeGroups][hasAttributeValue][:][0]<idx>s[-1][1]<ref>v [^0][vertices]>ref<t'
{
   "id": 129748,
   "name": "Polarized",
   "ns": "av"
}
{
   "id": 129898,
   "name": "False",
   "ns": "av"
}
bash $ 

Позвольте мне разбить дорожки (-w) на куски:

- [vertices][alias]:<polarized>[-1][ns]:<ca>[-1]<idx>k - найдет запись в vertices с "alias": "polarized" AND "ns": "ca" и сохранит индекс найденной записи в пространстве имен idx (заголовок пространства имен произвольный)

- [^0][edgeGroups][hasAttributeValue][:][0]<idx>s[-1][1]<ref>v - найдет (во всех записях) из edgeGroups / hasAttributeValue те, где первое значение соответствует сохраненному индексу (в пространстве имен idx), и сохранит в пространстве имен ref значение второго / соседнего значения.

- [^0][vertices]>ref<t - возвращает обратно к vertices и печатает запись по индексу (тегу), хранящемуся в пространстве имен ref

Раскрытие информации: я создатель jtc инструмента

...