использование ArangoDb / OrientDb для иерархической модели данных и поиска документов: правильное решение?

Я разрабатываю программное обеспечение для управления документами и оцениваю базу данных noSql для хранения и поиска данных.

Резюме: программное обеспечение действует как файловая система, когда элементы организованы в каталог и подкаталог.

Каждый элемент дерева может иметь n свойств, используемых для фильтрации и сортировки.

Элементы также могут быть в конечном итоге связаны друг с другом какими-либо другими отношениями (кроме родитель-потомок).

Количество элементов может быть относительно большим (несколько миллионов), а ключевыми функциями приложения должна быть постоянная производительность при извлечении данных (с фильтрами и сортировкой по свойствам) независимо от роста базы данных.

Мне нужно 3 ключевые функции:

  • Получить прямые дочерние элементы папки. результат должен быть доступен для просмотра, сортировки и фильтрации для каждого свойства документа.

  • Получить все дочерние элементы папки (все элементы поддерева). результат должен быть доступен для просмотра, сортировки и фильтрации для каждого свойства документа.

  • Получить всех родителей папки

Я новичок в noSql и на самом деле использую rdbms (сервер Sql), но столкнулся с проблемой производительности и всеми ограничениями, вызванными фиксированной схемой для свойств документа. Я оцениваю OrangoDb или OrientDb, потому что я думаю, что их функции (ориентированные на документы и графики) могут быть лучшим решением для моих потребностей в дизайне.

Можете ли вы помочь мне, предложив мне дизайн базы данных и запрос для этой 3 задачи?

номер мне нужно, чтобы результат запроса возвращал набор данных со столбцом для каждого свойства:

Es. doc1: p1: v1, p2: v2
    doc2: p1: v1, p3: v3

result:
    name | p1 | p2 | p3
    doc1   v1   v2   null
    doc2   v1   null v3

Я думаю создать элемент как:

{ 
  "_id": "_myItemId",
  "name`enter code here`" : "Item1",
  "itemType": "root / folder / file"   
  "parentItemId": "",
  "properties" : [ 
    { name: "Property1", formatType: 0, formatMask: "", value: "Value1" }, 
    { name: "Property2", formatType: 0, formatMask: "", value: "Value2" }, 
    { name: "Property3", formatType: 0, formatMask: "", value: "Value3" }  
  ] 
}

есть ли у вас какие-либо предложения по дизайну, способному решить 3 ключевые функции, описанные выше?

Спасибо


person Claudio    schedule 11.10.2015    source источник
comment
Вы видели этот пост на O'Reilly Radar? radar.oreilly.com/2015/07/   -  person weinberger    schedule 11.10.2015
comment
Я реализовал 2 коллекции в ArangoDb, Items (коллекция документов, которая содержит информацию о папках и файлах) и ItemsParents (коллекция краев, которая содержит отношения родитель-потомок элементов). Я разочарован производительностью, конечно, я делаю что-то не так... я вставил около 1 миллиона элементов, и производительность для простого подсчета элементов ужасна... это занимает 30/40 минут.. запрос AQL : LET u = ( FOR item IN Items RETURN item._key ) RETURN LENGTH(u) – где я делаю неправильно?   -  person Claudio    schedule 13.10.2015
comment
если вы хотите только подсчитать элементы и не нуждаетесь в их фактическом содержании, имеет смысл возвращать NULL вместо item.key — в этом нет необходимости получить доступ к членам, гораздо меньше данных перемещается.   -  person dothebart    schedule 19.10.2015
comment
Я работаю над похожим проектом, вы проверили влияние ответа на производительность ниже? @Клаудио   -  person Yahia Reyhani    schedule 24.07.2016


Ответы (1)


Подход к графовым базам данных сильно отличается от других типов СУБД. Вы можете «соединить» свои объекты (Вершины) с помощью Edges, прямой связи между одним объектом и другим. Итак, во-первых, вам не нужно хранить, например. «parentItemId» для каждого объекта, как если бы вы делали это в базе данных Sql или документа, но вместо этого у вас будет два/три или много объектов только с их конкретными данными; отношения будут обрабатываться ребрами, которые вы создаете между ними.

OrientdDb имеет очень хорошую документацию и несколько примеров, чтобы начать понимать концепции. Например: страница учебника: http://orientdb.com/docs/2.1/Tutorial-Working-with-graphs.html объясняет концепции графиков и содержит несколько хороших примеров.

В вашем конкретном случае у вас может быть два типа объектов (Вершина), Папка и Документ, а также Край, который вы называете, например. «ChildOf» (из документа в папку) или «Содержит» (из папки в документы). Затем вы можете выполнить множество запросов, чтобы найти отношения, даже указать уровень вложенности и т. д.

Вы можете создать рабочую схему, выполнив следующие шаги:

1 Создайте класс и граничные типы:

CREATE CLASS Document Extends V
CREATE CLASS Folder Extends V
CREATE CLASS ChildOf Extends E

2 Вставьте несколько документов

INSERT INTO Document SET Title = 'Document 1', Name = '..'
INSERT INTO Document SET Title = 'Document 2', Name = '..'
INSERT INTO Document SET Title = 'Document 3', Name = '..'

3 Вставить папки

INSERT INTO Folder SET Name = 'Folder 1'
INSERT INTO Folder SET Name = 'Folder 2'

4 Создайте ребра (отношения) между вершинами

CREATE EDGE ChildOf FROM #<specify document rid here> TO #<specify folder rid here>
...

Вы также можете создать папку как дочернюю для другой папки, установив один и тот же край «ChildOf» между двумя папками:

 CREATE EDGE ChildOf FROM #<specify children folder rid here> TO #<specify parent folder rid here>
...

5 Запросите свой график. Получите прямые дочерние элементы папки, используя операторы expand() и in():

Select expand(in('ChildOf')) From #<folder rid> Where ...

Получите все дочерние элементы папки, используя запрос Traverse для обхода всех дочерних элементов из начальной папки:

SELECT FROM (
     TRAVERSE out('ChildOf') FROM #<folder rid> WHILE $depth <= 3 //you can specify the maximum level of nesting
) where $depth > 0 //exclude the first element (the starting folder itself)

Получите всех родителей папки, используя оператор пересечения и графа «В»:

SELECT FROM (
         TRAVERSE in('ChildOf') FROM #<folder rid> 
    ) where $depth > 0 //exclude the first element (the starting folder itself)
//here you could filter only the "Folders"
where @class ='Folder'
person Stefano Castriotta    schedule 11.10.2015
comment
Спасибо, Стефано, сейчас я тестирую ArangoDb, но следующим шагом будет оценка OrientDb. - person Claudio; 13.10.2015
comment
Концепции одинаковы, ArangoDb и OrientDb чем-то похожи (у ArangoDb есть проприетарный язык, а у OrientDb язык, похожий на sql), вы можете использовать тот, который вам больше нравится (я не делаю спонсора ни для одного из них: )) - person Stefano Castriotta; 13.10.2015
comment
Я работаю над аналогичным проектом, вы проверяли производительность этого ответа? @клаудио - person Yahia Reyhani; 24.07.2016