将标签存储在图形数据库中

问题描述 投票:4回答:3

我已经找到了在relationaldocument数据库中设置标记系统的一些建议,但对于图形/多模型数据库没有任何建议。

我正在尝试在ArangoDB中为文档设置一个标记系统(让我们称之为“文章”)。我可以想到两种显而易见的方法来在像Arango这样的多模型(图形+文档)数据库中存储标签:

  • 作为每个文章文档中的数组(文档数据库样式)
  • 作为单独的文档类,每个标记作为唯一文档和边连接标记文档到文章文档(更接近关系数据库样式)

这些实际上是这两种主要方法吗?似乎都不理想。例如:

  • 如果我在每个文章文档中存储标签,我可以索引标签,并且可能ArangoDB正在优化他们使用的空间。但是,我无法使用图形功能来链接或遍历标记(或者我必须单独执行)。
  • 如果我将标记存储为单独的标记文档,当我只想获取文档上的标记列表时,它似乎是额外的开销(额外的查询)。

这引出了一个明确的问题:关于后一个选项,是否有任何简单的方法可以自动使连接的“标签”文档显示在文章文档中?例如。有一个数组属性,以某种方式'镜像'连接标签文件的tag.name属性?

一般建议也欢迎。

javascript graph-databases arangodb multi-model-database
3个回答
2
投票

您已经提到了大多数可用的决策标准。也许我可以添加更多:

文档中的关系标记可以使用数组索引对它们进行过滤,这可以快速对它们进行查询。但是,如果您想为该标记数组的每个项添加评级或解释,则无法进行。如果要计算标记的文档,这可能比计算源自特定标记的所有边缘更昂贵,或者可能找到与搜索条件匹配的所有标记。

多模型的一个强大功能是,您无需在两种方法之间做出决定。您可以使用边缘集合将带有属性的标记连接到文档,并在文档内部使用具有相同(平面)标记的索引数组。如果您发现所有(或大多数)查询只使用一种方法,请尝试转换其余方法并删除其他解决方案。如果这不起作用,您的应用程序只需要它们。

在这两种情况下,可以在子查询中查找其他标记文档:

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}

1
投票

遗憾的是,您明​​确询问关联文档是否会自动显示在您的文档中的答案是否定的。我已经制作了一个带有单独标签文档的ArangoDB图表,但我正在认真考虑将其转换为单个项目的属性,因为标签似乎遵循属性的标准,而不是相关项目。

迈克威廉姆森做了一篇很好的博客文章:https://mikewilliamson.wordpress.com/2015/07/16/data-modeling-with-arangodb/

他认为,单个顶点有很多边缘很慢,而流行的Tag顶点的边数就是这种情况。


0
投票

@JoachimBøgglid与Mike Williamson联系:https://mikewilliamson.wordpress.com/2015/07/16/data-modeling-with-arangodb/

我同意威廉姆森的观点,即“默认紧凑”通常是要走的路。然后,如果/当实际需要出现时,您可以从属性中提取节点。它还避免了创建过度互连的图形结构,这种结构对于所有类型的遍历查询都很慢。但是,我认为在这种情况下使用Tag顶点很好,因为您可以在标签上存储元数据(如count),并将其连接到其他标签和子标签。在标签的特定情况下,它似乎非常有用和可预见。拥有一个可以在需要时添加更多关系的节点也是非常可扩展的,因此您可以保持未来的选项更加开放(至少更简单)。

威廉姆森似乎同意:

“但并非所有内容都属于一个。任何包含复杂数据结构的属性(如”comments“数组或”tags“数组)都值得仔细研究,因为它可能作为自己的顶点(或顶点)有意义。”

@ropeladder的原始问题构成了额外开销(额外查询)的主要异议。我认为在现阶段过多地考虑性能可能是不成熟的优化。毕竟;额外查询可能很快,或者它可能包含在原始查询的结果集中。无论如何,我会引用这个:

“一般来说,尝试合并节点以保持查询时效率是不好的做法。如果我们根据我们想要询问的数据进行建模,则会出现域的准确表示。即使存储大量数据,图形数据库也可以保持快速的查询时间。在学习构建我们的图形而不对其进行非规范化时,学习信任我们的图形数据库非常重要。“ - 来自第64页,”避免反模式“一章,在”图形数据库“一书中,由创始人Eifrem共同撰写的一本书Neo4j,另一个非常受欢迎的原生图数据库。它是免费的,可在线获取:https://neo4j.com/graph-databases-book/

另见本文关于一些反模式(密集与稀疏图),以补充威廉姆斯点:https://neo4j.com/blog/dark-side-neo4j-worst-practices/


为了完整性,还包括额外的部分,以及那些想要深入探讨这个问题的人:

回答威廉姆森自己的标准,决定标签是否应该是一个节点,而不是将其作为文件的属性:

是否可以自己访问? (即:显示没有文档的标签)

是。系统中可用的浏览标签可能很有用。

你会在它上面运行图形测量(如GRAPH_BETWEENNESS)吗?

不确定。

它会自己编辑吗?

应该是。用户可以单独编辑它。也许管理员/主持人想要清理标签名称(正确的拼写错误),或者清理他们的结构(如果你有子标签)。

标签是否/可以拥有自己的关系? (假设你关心)

是。他们可以。子标签,其他类型的内容,而不仅仅是文档。

如果没有它的父顶点,这个属性是否应该存在?

是。即使删除了最后一个标记文档,标记也可能存在。有人可能希望稍后使用该标记,它表示您可能希望保留的域信息。


© www.soinside.com 2019 - 2024. All rights reserved.