创建可由其任何元素查询的文档的正确方法是什么?

时间:2017-12-16 18:58:00

标签: database mongodb mongoose mongodb-query

我正在开发一个项目,我希望通过搜索池中的任何元素来返回“池”中的所有文档。

例如,假设我们有3个池,每个池都有不同的文件,用字母标记

第1池:D

第2池:E, F, G, H

第3池:A

当我搜索A时,我想获得BCC。当我搜索A时,我还想获得BCI

如果我添加文档A, B, C, D, I,并且它满足第1池和第2池的条件,则应合并第1池和第2池,并且对任何value的任何搜索都应返回所有这些。< / p>

我知道如何低效地执行此操作(创建一个新文档,每个元素作为键,然后更新每个插入的所有文档),但我想知道是否有更好的方法?

提前致谢

1 个答案:

答案 0 :(得分:1)

我认为,对于像数据这样抽象的东西,特别是数据库文档,良好的可视化有助于概念化问题。尝试从维护一组深度不超过1的树的角度来看这个问题。具体来说,每个文档都是一个叶子,确定哪些是“池”的一部分的“规则”是根(即根是标签的子集,可以是叶子。

现在,你要说的是能够添加新的叶子。如果此叶子能够连接到多个根,则应合并这些根,这意味着更新根目录并将每个叶子从受影响的树指向此新根。

否则,你最终得到的是需要从新叶子跳到它连接到的每个根,然后到每个其他叶子。但是彼此的叶子也可能连接到其他根,这意味着你可以像这样任意次数跳跃。这是一个不理想的情况。

为了使此查询更有效,您需要确定这些“根”的内容并相应地更新它们。例如,您可以根据需要决定保留“池”文档并将这些“池”合并在一起,例如通过拥有labels字段,该字段是要包含在池中的标签数组。合并只是合并阵列本身的问题。或者,您可以使用公共ObjectId(不一定附加到任何特定文档)并将此值用作一种“伪根节点”来代替具有文档。您可以探索多种选择。但是,一般情况下,您应该尝试将单个文档的字段值检查减少到单个值检查(例如,不要在每个文档中保留其他“相关”标签的数组!)。

无论您的方法如何,请记住这些树结构,考虑根据MongoDB查询遍历节点意味着什么,并确定如何遍历节点以便1)确保“跳”的数量“节点之间需要一个恒定时间操作,2)确保您可以高效可靠地合并这些根,而不会有数据丢失的风险。”

最后,如果您发现更新查询太慢,那么您可能会遇到索引问题。使用适当的索引,甚至数百万个文档的集合更新都不应该花费任何时间。此外,如果您没有进行multi更新,而是为每个文档运行单独的更新,那么您的更新写得很糟糕,因为您将遇到O(n)搜索时间和网络开销,这将使你的更新减慢到爬行。