Хранение тегов в базе данных графа

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

Я пытаюсь настроить систему тегов для документов (назовем их "статьи") в ArangoDB. Я могу придумать два очевидных способа хранения тегов в многомодельной базе данных (график + документ), такой как Arango:

  • как массив в каждом документе статьи (стиль базы данных документа)
  • как отдельный класс документа с каждым тегом в качестве уникального документа и ребрами, соединяющими документы тега с документами статьи (что-то ближе к стилю реляционной базы данных)

Это два основных способа сделать это? Ни то, ни другое не кажется идеальным. Например:

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

Что приводит меня к явному вопросу: что касается последнего варианта, существует ли какой-либо простой способ автоматического отображения связанных документов с тегами в документах статьи? Например, есть свойство массива, которое как-то "зеркально отображает" tag.name свойства связанных тегов документов?

Общие советы также приветствуются.

2 ответа

@Joachim Bøgglid связан с Майком Уильямсоном: https://mikewilliamson.wordpress.com/2015/07/16/data-modeling-with-arangodb/

Я бы согласился с Уильямсоном, что "Компакт по умолчанию" - это вообще путь. Затем вы можете извлечь узлы из свойств, если / когда возникнет реальная потребность. Это также позволяет избежать создания чрезмерно взаимосвязанной структуры графа, которая будет медленной для всех видов обходных запросов. Тем не менее, я думаю, что в этом случае хорошо иметь вершину тега, потому что вы можете хранить метаданные в теге (например, счетчик) и подключать его к другим тегам и подтэгам. Это кажется очень полезным и предсказуемым в конкретном случае тегов. Наличие узла, к которому вы можете добавить больше связей, если / когда они вам нужны, также очень расширяемо, поэтому вы сохраняете свои будущие параметры более открытыми (по крайней мере, более легкими).

Кажется, Уильямсон соглашается:

"Но не все принадлежит друг другу. Любой атрибут, который содержит сложную структуру данных (например, массив" comments "или массив" tags "), заслуживает небольшого изучения, поскольку он может иметь смысл как отдельная вершина (или вершины)".

Оригинальный вопрос от @ropeladder ставит основное возражение по поводу дополнительных накладных расходов (дополнительный запрос). Я думаю, что это может быть преждевременной оптимизацией, чтобы слишком много думать о производительности на данном этапе. В конце концов; дополнительный запрос может быть быстрым или может быть включен в набор результатов исходного запроса. В любом случае я бы процитировал это:

"В общем, плохая практика пытаться объединять узлы, чтобы сохранить эффективность времени запроса. Если мы будем моделировать в соответствии с вопросами, которые мы хотим задать для наших данных, появится точное представление домена. Графовые базы данных поддерживают быстрое время запросов даже при хранении огромных объемов данных. Умение доверять нашей базе данных графов важно, когда вы учитесь структурировать наши графы без их денормализации ". - со страницы 64, глава" Избегание анти-паттернов ", в книге" Базы данных графов ", книга, написанная в соавторстве с Эйфремом, основателем Neo4j, еще одна очень популярная родная графовая база данных. Это бесплатно и доступно онлайн здесь: https://neo4j.com/graph-databases-book/

См. Также эту статью о некоторых антишаблонах (плотные и разреженные графы), чтобы дополнить баллы Уильямсона: https://neo4j.com/blog/dark-side-neo4j-worst-practices/


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

Отвечая на собственные критерии Уильямсона, чтобы решить, должен ли тег быть Узлом сам по себе, вместо того, чтобы оставить его как свойство в документе:

Будет ли он доступен сам по себе? (то есть: показ тегов без документа)

Да. Просмотр тегов, доступных в системе, может быть полезен.

Будете ли вы проводить измерение графика (например, GRAPH_BETWEENNESS) на нем?

Неуверенный.

Будет ли он редактироваться самостоятельно?

Да, возможно. Пользователь может редактировать его отдельно. Возможно, администратор / модератор хочет очистить имена тегов (исправить орфографические ошибки) или очистить их структуру (если у вас есть под-теги).

Есть ли у тегов собственные отношения? (если вы заботитесь)

Да. Они могли. Под-теги, другие виды контента, кроме просто документов.

Будет ли этот атрибут существовать без родительской вершины?

Да. Тег может / должен существовать, даже если последний тегированный документ был удален. Кто-то может захотеть использовать этот тег позже, и он представляет информацию о домене, которую вы, возможно, захотите сохранить.


Вы уже упомянули большинство доступных критериев принятия решения. Может быть, я могу добавить еще:

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

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

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

LET docs=(FOR ftDoc IN FULLTEXT(articles, 'text', 'search')
    COLLECT tags = ftDoc.tags INTO tags RETURN {tags, ftDoc})
LET tags = FLATTEN(FOR t IN docs[*].tags RETURN t)
LET otherArticles = (FOR oneTag IN tags 
    FOR oneD IN articles FILTER oneTag IN oneD.tag RETURN oneD._key)
RETURN {articles: docs, tags: tags, otherArticles: otherArticles}

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

Майк Уильямсон сделал хороший пост в блоге об этом: https://mikewilliamson.wordpress.com/2015/07/16/data-modeling-with-arangodb/

Он утверждает, что наличие большого количества ребер в одной вершине является медленным, и это было бы в случае количества ребер в популярной вершине тега.

Другие вопросы по тегам