Существует ли какая-либо структура данных или база данных, которые могут обрабатывать инструкции выражения пути и запросы выражения пути?

#database #data-structures

#База данных #структуры данных

Вопрос:

Мне нужно смоделировать граф (или его можно рассматривать как рекурсивное дерево (ы), поскольку обычно оно состоит из одного или небольшого числа корней) на основе объектов, имеющих дочерние элементы:

 a hasChildren (b, c)
b hasChildren (d, e)
c hasChildren (f, g)
d hasChildren (h, a)
  

Теперь существуют неявные пути, a / c / f, а также рекурсивные: a / b / d /a/ b / d /…

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

Под выражением пути я подразумеваю что-то вроде этого:

 a/b/** -> color = "blue"
  

это означало бы, что все пути, начинающиеся с a /b /, имеют свойство color = «blue». Итак, если бы я запросил цвет a / b / d / a / b / d / a, он вернул бы синий. Но если бы я запросил цвет только a, то на данный момент его нет.

Другими выражениями могут быть:

 **/d/h
a/b/[color="blue"]
a/**/h
  

Итак, это будет использоваться для создания инструкций. Мне нужен аналогичный способ выполнения запросов. Мне нужны простые запросы, такие как:

 a/b/d
  

и более сложные из них, такие как:

 a/**[color="blue"]  -- descendants that have attribute color = "blue". This could be infinite in recursive case so we can put a restriction on this type of query to have it make sense, like does such a path exist, or just return first one or something.
  

Кроме того, в любое время могут быть добавлены дополнительные узлы.

у a есть дети (b, c, x, y, z)

Мне нужно, чтобы запросы после этого соответствовали соответствующим образом всем инструкциям. Итак, другими словами, я не могу просто запустить запрос и установить свойство для всех результатов, поскольку тогда это не будет применяться к новым вещам, добавленным позже.

И, конечно, мне нужно, чтобы это было очень быстро 🙂 У меня было бы порядка 1000 узлов, 1000 выражений выражения пути и запрос на 100 000 выражений пути.

Есть ли что-то, что хорошо справляется с подобными вещами?

Я просмотрел что-то вроде RDF / OWL, но, похоже, у него нет никакой поддержки путей.

Комментарии:

1. Различен ли каждый путь через точки? например, разрешено ли следующее? a /b / c / d / e, f/b /c/g / h, f/ d /c/ h / j. Все три пути проходят через b / c, поэтому простое следование родительскому потоку не идентифицирует уникальный путь, только все возможные соединения. Должен ли каждый путь иметь уникальный идентификатор?

2. Я не совсем уверен, что вы имеете в виду. Три вещи, которые вы перечислили, являются тремя разными путями, потому что они включают различную последовательность родительский-дочерний. a / b / c совпадает только с a / b / c (идентификатор), но a / b / c и b / c и a / b и a / c — это все разные пути.

Ответ №1:

Если я правильно понимаю ваш вопрос, вы говорите о запросе на основе выводов, сделанных на основе отношений объектов. Если это так, вам нужно взглянуть на RDF и SPARQL http://www.w3.org/TR/rdf-sparql-query / и все поле семантического содержимого.

Комментарии:

1. RDF не может обработать это самостоятельно, слишком низкий уровень. SQARQL касается запросов, которые не являются проблемой. Проблема в том, как создать инструкцию, предметом которой являются результаты запроса.

2. Я только что потратил кучу времени на изучение Jena, но я ничего не вижу о работе с путями. Мне нужны выражения пути и запросы к выражениям пути и… Я ничего не вижу о подобных вещах в документах Jena. И я не нахожу материал о правилах / выводах в документах graph db, так что … похоже, не могу найти единого решения, которое выполняет оба утверждения для выражений пути и запрашивает выражения пути.

Ответ №2:

В подобной проблеме я в конечном итоге реализовал свой собственный Trie (в моем случае, на Java) с классом Node, который содержит дочерние узлы и способен проверять, соответствует ли ему оставшийся путь (что подразумевает, что все его предки подсвечивали зеленым цветом свою часть пути перед ним.

Это довольно быстро, и код довольно компактный. Надеюсь, это поможет!

Комментарии:

1. Trie будет хорошо обрабатывать определенный тип запросов, но я ищу общий подход к гораздо большему количеству типов запросов и инструкций, чем этот.

Ответ №3:

не уверен, что это именно то, что вам нужно, но для меня это звучит как предложения oracle CONNECT BY и START WITH.

например, у вас могла бы быть таблица под названием NODES с этими столбцами:

  • ИДЕНТИФИКАТОР как первичный ключ
  • PARENT_ID, указывающий на идентификатор этой же таблицы
  • ЦВЕТ … и все, что вам еще нужно

а затем выполните запрос такого рода

ВЫБЕРИТЕ ID, PARENT_ID, COLOR ИЗ УЗЛОВ, НАЧИНАЮЩИХСЯ С PARENT_ID РАВНО НУЛЮ, ПОДКЛЮЧИТЕСЬ ПО ПРЕДЫДУЩЕМУ ID = PARENT_ID

добавляя любое предложение, которое вам нужно, т. Е. ГДЕ COLOR = ‘BLUE’, оно также содержит условие nocycle для вашего примера a / b / d / a / b / d.

вот дополнительная информация

http://www.adp-gmbh.ch/ora/sql/connect_by.html

Комментарии:

1. Спасибо, но опять же, это не обрабатывает как создание инструкций для выражений пути, так и затем запрос к ним.

Ответ №4:

Насколько я понимаю вопрос, вы хотите смоделировать дерево, которое может поддерживать рекурсию. Я могу ответить с точки зрения дизайна таблицы sql. Для этого есть 2 способа: 1) используйте модель смежности, в которой вы будете хранить ключ в одном столбце, а дочерний — в другом

 Parent Child
Null   A
A      B
A      C
B      D
B      E
  

2) Вы можете использовать левое значение и правое значение, определенные как модель вложенного набора, и это обеспечивает хорошую производительность. Прочитайте эту статью от гуру SQL Джо Селко, и она даст вам больше подсказок
http://en.wikipedia.org/wiki/Nested_set_model

Комментарии:

1. Это моделирует график / дерево, но это делает любая графическая база данных. Это то, с чем мне нужно разобраться.

Ответ №5:

Графическая модель сильно отличается от реляционной модели, я думаю, вам следует использовать какую-нибудь базу данных NoSQL.

Поиск узлов по частичным путям реализован в MongoDB только для деревьев, но должен осуществляться с помощью простой в написании графической реализации на прикладном уровне: http://www.mongodb.org/display/DOCS/Trees in MongoDB

Существует несколько баз данных, ориентированных на графы:

Также рекомендуем вам прочитать эту статью: Запрос данных RDF с точки зрения базы данных Graph, особенно главу 3.2 о языке запросов graph

Комментарии:

1. Спасибо за отличную информацию, но… Я все еще ничего не вижу о создании инструкций на основе выражений пути, которые затем используются при запросе.

Ответ №6:

Я действительно не уверен в каких-либо готовых материалах для решения такого рода проблем, но если бы я собирался моделировать древовидную структуру, я бы, вероятно, просто создал набор классов c # (или какой-либо другой объектно-ориентированный язык). Общая идея заключается в том, что вы настраиваете класс для узла, затем класс для самого графика с функциями для добавления узлов, удаления узлов, поиска определенных путей и т.д. (устанавливаете «цвет» путей). Затем вы могли бы даже сохранять матрицы, представляющие различные графические структуры и пути, в БД, если это то, что вы ищете.

Мне трудно уточнить, когда в вашем вопросе на самом деле не указано, какой подход вы хотите использовать. Вы ищете что-то готовое для этого? Если нет, ознакомьтесь с этим набором руководств по созданию графиков на c # (хотя те же концепции могут применяться к любому языку OO). http://msdn.microsoft.com/en-us/library/ms379574.aspx

Комментарии:

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