Итерационный объект массива в Couchbase

#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, и он сработал.