Итеративный запрос к ArangoDB с использованием AQL

Я сохранил данные JSON в коллекции ArangoDB в следующем формате.

{ 
  "data": {
    "1":   [ {"db_name": "DSP"}, {"rel": "2"} ], 
    "2":   [ {"rel_name": "DataSource"}, {"tuple": "201"}, {"tuple": "202"}, {"tuple": "203"} ],
    "201": [ {"src_id": "Pos201510070"}, {"src_name": "Postgres"}, {"password": "root"}, {"host": "localhost"}, {"created_date": "20151007"}, {"user_name": "postgres"}, {"src_type": "Structured"}, {"db_name": "postgres"}, {"port": "None"} ],
    "202": [ {"src_id": "pos201510060"}, {"src_name": "Postgres"},{"password": "root"}, {"host": "localhost"}, {"created_date": "20151006"}, {"user_name": "postgres"}, {"src_type": "Structured"}, {"db_name": "DSP"}, {"port": "5432"} ],
    "203": [ {"src_id": "pos201510060"}, {"src_name": "Postgres"}, {"password": "root"}, {"host": "localhost"}, {"created_date": "20151006"}, {"user_name": "postgres"},{"src_type": "Structured"},{"db_name": "maindb"},{"port": "5432"} ]
  }
}

Я новичок в ArangoDB. Я понятия не имею о хранении и запросе данных из ArangoDB. В моих данных нет предопределенного ключа, и данные заполняются со временем. Мои данные похожи на полуструктурированные данные, которые не имеют фиксированного количества атрибутов, и немного сложны из-за своей итеративной структуры списка.

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

Во-вторых, я хочу запросить эти данные следующим образом: указав любой ключ (заранее неизвестный, указав его во время выполнения), или указав комбинации пары ключ и значение, например Key1 == value1, или комбинацию с помощью AND или OR логические операторы типа Key1 == value1 AND Key2 == value2 OR Key3== value3.

Итак, как мы можем перебирать приведенные выше данные?


person Mrityunjay Singh    schedule 27.10.2015    source источник
comment
Я пробовал запрос For u в Collecton_name return u Это похоже на запрос реляционных данных с помощью select * from table_name;   -  person Mrityunjay Singh    schedule 27.10.2015
comment
Немного неясно, какой результат запроса действительно нужен. Например, для перебора всех атрибутов в каждом документе можно использовать вложенные циклы FOR в AQL следующим образом: FOR doc IN collection LET attributes = ATTRIBUTES(doc.data) FOR attribute IN attributes RETURN { key: attribute, value: doc.data[attribute] }   -  person stj    schedule 27.10.2015
comment
Я хочу получить доступ только к тем, где db_name == main_db, или мне нужен список значений, соответствующих имени атрибута, например src_type и т. Д.   -  person Mrityunjay Singh    schedule 27.10.2015
comment
Спасибо, я также хочу знать, можем ли мы сформулировать запрос, как указано выше, при запуске, когда количество условий увеличивается.   -  person Mrityunjay Singh    schedule 27.10.2015
comment
Можете ли вы объяснить, почему ваша структура данных использует массив объектов, каждый из которых содержит только один атрибут? Похоже, ваша модель данных не определена должным образом. Чтобы лучше понять вашу проблему, может помочь, если вы опубликуете эквивалентный SQL-запрос, который вы бы использовали для решения проблемы.   -  person CodeManX    schedule 06.11.2015


Ответы (1)


Если вы действительно хотите хранить данные в такой структуре, без каких-либо предопределенных имен атрибутов, вы все равно можете перебирать данные, конвертируя их в нормализованную структуру на лету.

Следующий запрос AQL создает плоский список пар ключ / значение для каждого документа:

FOR doc IN collection 
  LET attributes = ATTRIBUTES(doc.data) 
  FOR attribute IN attributes 
    FOR arrayItem IN doc.data[attribute] 
      LET key = ATTRIBUTES(arrayItem)[0] 
      LET value = arrayItem[key] 
      RETURN { _key: doc._key key: key, value: value }

Результат этого запроса будет примерно таким:

[ 
  { 
    "_key" : "864582648369", 
    "key" : "password", 
    "value" : "root" 
  }, 
  { 
    "_key" : "864582648369", 
    "key" : "db_name", 
    "value" : "postgres" 
  }, 
  { 
    "_key" : "864582648369", 
    "key" : "port", 
    "value" : "None" 
  }, 
  ...
]

Теперь вы можете легко применить фильтрацию, добавив выбранные условия фильтрации:

FOR doc IN collection 
  LET attributes = ATTRIBUTES(doc.data) 
  FOR attribute IN attributes 
    FOR arrayItem IN doc.data[attribute] 
      LET key = ATTRIBUTES(arrayItem)[0] 
      LET value = arrayItem[key] 
      FILTER key == 'password' || key == 'port' || (key == 'db_name' && value == 'postgres') 
      RETURN { _key: doc._key, key: key, value: value }

Обратите внимание, что при изменении структуры данных (больше / меньше уровней вложенности) вышеуказанное больше не будет работать. Запрос предполагает документы со структурой, представленной в вопросе.

person stj    schedule 27.10.2015
comment
Thanx stj ...., Не могли бы вы подсказать мне, как я могу снять ограничение, касающееся большего / меньшего уровней вложенности .... - person Mrityunjay Singh; 27.10.2015
comment
Есть ли способ снять это ограничение ?? - person Mrityunjay Singh; 27.10.2015
comment
и не могли бы вы предложить мне хороший учебник для меня как новичка в ArangoDB ?? - person Mrityunjay Singh; 27.10.2015
comment
Структура жестко запрограммирована в написанном мною запросе. Для каждого уровня вложенности существует FOR цикл. Я не думаю, что есть способ обрабатывать произвольно структурированные документы в AQL, ничего не зная о структуре. Думаю, это будет сложно и с другими языками. Поэтому я предлагаю определить хотя бы минимальную структуру и использовать ее для всех документов. - person stj; 28.10.2015
comment
Re tutorials: официальная документация находится на docs.arangodb.com, а также здесь есть список рецептов из кулинарных книг: docs.arangodb.com/cookbook - person stj; 28.10.2015
comment
Спасибо, stj .... Скажите еще кое-что, если все данные внутренне преобразованы в структуру, показанную выше, как {{_key: 864582648369, key: password, value: root}, {_key: 864582648369, key: db_name, значение: postgres}, {_key: 864582648369, ключ: порт, значение: Нет}, ..} - person Mrityunjay Singh; 28.10.2015
comment
Тогда лучше ли преобразовать наши данные явно в приведенную выше структуру, а затем сохранить их в ArangoDB вместо структурированных данных, хранящихся в моей коллекции, которую я дал ранее? - person Mrityunjay Singh; 28.10.2015
comment
Вы можете хранить такие объекты, как { "_key" : "864582648369", "key" : "password", "value" : "root" }, как отдельные документы в коллекции. Тогда запросы и фильтрация станут проще. Однако, если несколько из этих объектов логически принадлежат друг другу (по-видимому, они принадлежат друг другу, потому что они были сгруппированы по некоторым ключам в исходных данных), тогда вы можете также захотеть сохранить ключ группы в документе, например { "_key" : "864582648369", "key" : "password", "value" : "root", "group" : "101" }. Но насколько это разумно, зависит от цели данных и от того, какие запросы вы собираетесь запускать по ним. - person stj; 29.10.2015
comment
В приведенных выше данных json я хочу получить документы только по определенной паре ключ-значение, предположим, я хочу получить документ, где db_name - это postgres, поэтому я сделал условие фильтра, как указано выше (key == 'db_name' && value == 'postgres'), но этот запрос возвращает пустой набор. Если я использую || затем возвращает дополнительный документ. Пожалуйста, сообщите мне, доступен ли какой-либо другой подходящий вариант для вышеуказанного запроса. Я использую формат {_key: 864582648369, ключ: пароль, значение: корень, группа: 101} для хранения объекта json. - person Mrityunjay Singh; 30.12.2015
comment
Просто попробовал с данными из приведенного выше примера, и добавление условия FILTER key == 'db_name' && value == 'postgres' возвращает { "_key" : "18640413109", "key" : "db_name", "value" : "postgres" } нормально. &&, конечно, не будет работать, если ключ == db_name и значение == postgres содержатся в разных подчастях, но в данных примера он должен работать нормально. Если нет, не могли бы вы показать данные и запрос, который вы используете? Спасибо. - person stj; 04.01.2016
comment
Привет, stj, спасибо, что помогли мне. Пожалуйста, скажите мне одну вещь, если я использую вложенный ключ-значение, как показано в опубликованном вопросе, n, если я повторяю коллекцию, то как я могу определить значение основных ключей в приведенной выше структуре документа. - person Mrityunjay Singh; 11.05.2016
comment
Например, {data: {1: [{db_name: DSP}, {rel: 2}], 2: [{rel_name: DataSource}, {tuple: 201}, {tuple: 202}, {tuple: 203}] , 201: [{src_id: Pos201510070}, {src_name: Postgres}, {пароль: root}, {host: localhost}, {created_date: 20151007}, {user_name: postgres}, {src_type: Structured}, {db_name: postgres }, {port: None}],}} Как я могу получить ключи 1, 2, 201 и т. д. в этом документе .. - person Mrityunjay Singh; 11.05.2016
comment
Здравствуйте, stj! Пожалуйста, скажите мне ответ на вышеуказанный вопрос, как мы можем определить значение ключей как 1, 2, 201 и т. Д. - person Mrityunjay Singh; 15.06.2016