#arrays #loops #object #couchbase #n1ql
Вопрос:
Как выполнить итерацию объекта массива, чтобы получить конкретную пару значений ключа из объекта JSON. Я использую сервер Couchbase. Пожалуйста, предложите N1QL для Couchbase.
Ниже приведен мой формат JSON
{
"A":{
"B":{
"C": {
"D":[
{
"attr":[
{
"Name" : "abc"
}
],
"Name" : "outer"
}
],
"E":[
{
"attr":[
{
"Name" : "xyz"
}
],
"Name" : "outer1"
}
]
}
}
}
}
Хотите получить значение атрибута Name внутри каждого массива объекта C. Пожалуйста , обратите внимание, что внутри массива есть два поля с одинаковым именем, поэтому хотите просто получить доступ к внешнему. Пара ключевых значений внутри C является динамической.
заранее спасибо!
Комментарии:
1. Отличная возможность изучить рекурсию, не упускайте ее из виду.
Ответ №1:
Если вы действительно ищете все имена объектов пути A. B. C, используйте следующее выражение
ARRAY v.Name FOR v WITHIN A.B.C WHEN v.Name IS NOT MISSING END
SELECT ARRAY v.Name
FOR v WITHIN d.A.B.C
WHEN v.Name IS NOT MISSING
END AS val
FROM [{ "A":{ "B":{ "C": { "D":[{"Name" : "test1", "state" : "state1"} ],
"E":[{"Name" : "test2", "state" : "state2"} ],
"F":[{"Name" : "test2", "state" : "state2"} ]
}
}
}
}
] AS d;
{
"val": [
"test1",
"test2",
"test2"
]
}
Если вам нужно выбрать только некоторые, вам нужно, чтобы в этом объекте постоянно присутствовало какое-то другое поле.
ARRAY v.Name FOR v WITHIN A.B.C WHEN v.Name IS NOT MISSING AND v.attr IS NOT MISSING END
SELECT ARRAY v.Name FOR v WITHIN d.A.B.C WHEN v.Name IS NOT MISSING AND v.attr IS NOT MISSING END
FROM [{ "A":{ "B":{ "C": { "D":[ { "attr":[ { "Name" : "abc" } ], "Name" : "outer" } ], "E":[ { "attr":[ { "Name" : "xyz" } ], "Name" : "outer1" } ] } } } }] AS d;
Если вы уже знаете заранее определенный путь (не используйте рекурсивный).
Постройте МАССИВ значений объекта динамического поля. Поскольку значение уже является МАССИВОМ, сгладьте его на 1 уровень, затем выполните итерацию по МАССИВУ и получите имя. Если вам нужен уникальный, используйте ARRAY_DISTINCT()
ARRAY v.Name FOR v IN ARRAY_FLATTEN((ARRAY nv FOR n:nv IN d.A.B.C END),1) END
SELECT ARRAY v.Name FOR v IN ARRAY_FLATTEN((ARRAY nv FOR n:nv IN d.A.B.C END),1) END AS obj
FROM [{ "A":{ "B":{ "C": { "D":[ { "attr":[ { "Name" : "abc" } ], "Name" : "outer" } ], "E":[ { "attr":[ { "Name" : "xyz" } ], "Name" : "outer1" } ] } } } }] AS d;
Комментарии:
1. Большое вам спасибо !! Это решение действительно сработало для упомянутого JSON. Однако есть 2 поля с одинаковым именем, и я хочу получить конкретное. Не могли бы вы, пожалуйста, предложить решение для этого. Я обновляю JSON.
2. решение для оформления заказа
3. Спасибо!! Включил еще один атрибут в условие where, и он сработал.