ArangoDB 在图形数据库中存储标记

mrphzbgm  于 2022-12-09  发布在  Go
关注(0)|答案(3)|浏览(171)

我找到了一些关于在relationaldocument数据库中设置标记系统的建议,但是没有关于图形/多模型数据库的建议。
我正在尝试在ArangoDB中为文档(让我们称它们为“文章”)建立一个标记系统。我可以想到两种明显的方法来在像Arango这样的多模型(图形+文档)数据库中存储标记:

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

实际上,这两种方法是不是都不理想呢?例如:

  • 如果我在每个文章文档中存储标签,我可以为标签建立索引,并且ArangoDB可能会优化它们使用的空间。但是,我不能使用图表功能来链接或遍历标签(或者我必须单独完成)。
  • 如果我将标记存储为单独的标记文档,那么当我只想获取文档上的标记列表时,这似乎会产生额外的开销(额外的查询)。

这就引出了一个明确的问题:关于后一种选择,是否有简单的方法可以自动使连接的“标记”文档显示在文章文档中?例如,有一个数组属性,以某种方式“镜像”连接的标记文档的tag.name属性?
也欢迎一般性的建议。

xuo3flqw

xuo3flqw1#

@Joachim Bøggild与迈克·威廉姆森有联系:https://mikewilliamson.wordpress.com/2015/07/16/data-modeling-with-arangodb/
我同意威廉姆森的观点,**“默认情况下紧凑”是 * 通常 * 的做法。如果/当实际需要出现时,您可以从属性中提取顶点(也称为. nodes)。**它还避免了创建过度互连的图结构,这种结构对于所有类型的遍历查询来说都很慢。

**然而,在这种情况下,**我认为标记顶点(即术语中的“documents”),因为这样就可以在标记上存储元数据(比如count),并将其连接到其他标签和子标签上。在标签的特定情况下,这似乎非常有用,并且可以立即预见。有了一个顶点,如果需要,可以添加更多的关系,也是非常可扩展的,因此您可以让未来的选择更加开放(至少更容易)。

似乎威廉姆森同意标签值得特别考虑
“但并不是所有的东西都属于同一个集合。任何包含复杂数据结构的属性(如“comments”数组或“tags”数组)都值得仔细检查,因为它 * 可能 * 作为自己的一个顶点(或多个顶点)有意义。”
@ropeladder最初的问题提出了主要的反对意见,即它将需要额外的开销(一个额外的查询)。我认为在这个阶段考虑太多性能可能是过早的优化。这个额外的查询可能很快,或者它实际上可能与原始查询连接并包含在原始查询中。
“通常,尝试合并节点以保持查询时效率是一种不好的做法。*如果我们根据希望对数据提出的问题进行建模,即使在存储大量数据的情况下,图形数据库也能保持快速的查询速度。在学习如何在不对图形进行反规范化的情况下构建图形时,学会信任我们的图形数据库是非常重要的。”- 摘自《图形数据库》一书第64页“避免反模式”一章,该书由Eifrem合著,Eifrem是另一个非常流行的本Map形数据库Neo4j的创始人。它是免费的,可在以下网址获得:https://neo4j.com/graph-databases-book/
另请参阅本文中关于一些反模式(密集图与稀疏图)的内容,以补充Williamson的观点:https://neo4j.com/blog/dark-side-neo4j-worst-practices/

  • 为完整起见,我们还为那些想更深入地探讨这个问题的人提供了额外的部分:*

回答威廉姆森自己的标准,决定某个东西是否应该是它自己的上的顶点/节点,而不是将它作为文档顶点上的属性:
它是否可以独立访问?(即:显示标记而不显示文档)
是的。浏览系统中可用的标签可能会很有用。
您是否要对它运行图形测量(如GRAPH_BETWEENNESS)?
不确定。应该不会。
它会自己编辑吗?
是的,可能。用户可以单独编辑它。也许管理员/版主想清理标签名称(纠正拼写错误),或者清理它们的结构(如果你有子标签)。
标签是否/可能有自己的关系?(假设您关心)
是的。它们可以。子标签,或者其他种类的内容,而不仅仅是文档。实际上,能够点击一个标签并立即看到带有该标签的所有文档是非常有用的。这可能是次优的,因为标签存储为每个文档上的属性数组。而图形数据库从根本上优化了查询与其他顶点相邻的顶点(也称为.节点)的情况。
如果没有其父顶点,该属性是否存在/应该存在?
是的。即使最后一个标记的文档被删除,标记也可能/应该存在。以后可能有人要使用该标记,它代表您可能要保留的域信息。

ycl3bljg

ycl3bljg2#

你已经提到了大多数可用的决策标准,也许我可以再补充一些:
文档中的关系标记可以使用数组索引来筛选它们,这可以使查询速度更快。但是,如果您想为该标记数组的每一项添加评级或解释,则无法这样做。如果您想计算标记的文档,这可能也比计算源自特定标记的所有边缘更昂贵,或者可能查找匹配搜索条件的所有标记。
多模型的一个优点是,你不需要在两种方法之间做出选择。你可以有一个边缘集合,将带有属性的标签连接到你的文档,并有一个索引数组,具有相同的(flat)标签。如果您找到所有如果你的大多数查询都只使用一种方法,那么尝试转换剩下的方法并删除另一种方法。如果这样做不起作用,那么你的应用程序就需要这两种方法。
在这两种情况下,都可以在子查询中查找旁边的其他标记文档:

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}
whlutmcx

whlutmcx3#

很遗憾,对于您明确提出的问题,即连接的文档是否会自动显示在您的文档中,答案是否定的。我已经用单独的标记文档制作了一个ArangoDB图,但我正在认真考虑将其转换为单个项的属性,因为标记似乎遵循作为属性而不是相关项的标准。
Mike威廉姆森对此做了一篇很好的博客文章:https://mikewilliamson.wordpress.com/2015/07/16/data-modeling-with-arangodb/
他认为,从一个顶点得到很多边是很慢的,而从一个流行的Tag顶点得到很多边就是这种情况。

相关问题