繁体   English   中英

表示Mongo DB中的对等关系

[英]Representing reciprocal relationships in Mongo DB

我在mongoDB中有一组东西(基因)。 我正在进行分析,以查看每个基因与另一个基因的相似程度,我想将该信息存储在数据库中。 对于每个基因,我目前在数据库中有不同的文档,其中包含诸如该基因来自什么物种以及DNA序列等信息。 当然,每一个都有唯一的标识符_id

当我进行分析时,我将获得有关百分比相似基因(其perc_identity )的信息。 通常,分析可以返回的下限是perc_identity(A:B) == 90 %,因此每个基因不一定有数字,但是每个关系都是对等的(例如,如果perc_identity(A:B) == 90那么perc_identity(B:A) == 90 )。

我的问题是什么是存储这些关系的最佳数据模型,以便我可以检索它们以进行进一步分析? 换句话说,有时我会想抓住perc_identity > 95所有对。 其他时候,我想获得一个特定基因的所有匹配。 如果重要的话,获取perc_identity的初始分析只需要执行一次,并且已经花费了相当长的时间,因此对插入的性能影响不如对以后的分析进行检索。

我有一些想法(如果重要的话,我正在python中使用mongoDB):

1)在每个基因的文档中,有一个子文档,其中包含所有匹配的_id和其perc_identity 例如:

{
    _id: geneA,
    dna_seq: 'AACTG...',
    species: 'Homo sapiens',
    hits:{
        geneA: 100,
        geneB: 92,
        geneC: 70,
    }
},
{
    _id: geneB,
    dna_seq: 'AATTG...',
    species: 'Pan troglodytes',
    hits:{
        geneA: 92,
        geneB: 100,
    }
},
{
    _id: geneC,
    dna_seq: 'ATGGC...',
    species: 'Homo erectus',
    hits:{
        geneA: 70
        geneC: 100
    }
}

显然,这将导致数据重复,但这与从初始分析中吐出数据的方式最接近。 大多数时候,我不会关心gene文档中的大多数其他数据,因此我不清楚是否会降低信息嵌套的速度。 我也不清楚是否会有一种有效的查询方式,例如all perc_identity > 90 每次我要进行分析时,我都会检索到所需数据量的两倍。

2)有一个单独的文档,其中仅包含基因_id s及其所有命中结果。 例如:

{
    _id: 'hits',
    geneA: {
        geneA: 100
        geneB: 92
        geneC: 70
    },
    geneB: {
        geneA: 92
        geneB: 100
    },
    # etc
}

这样做的好处是我完全不必弄乱基因文件。 我也可以有不同的hits集合,如果有什么差别。 另一个好处是,将有约5万个基因记录,但其中只有1-2%的基因记录完全没有命中,因此查询不必费心检查大多数文档。 否则,这对我来说似乎与(1)非常相似。

3)某种没有冗余的方法。 我想不出做到这一点的好方法。 我想到的坏方法是让perc_identity作为键,然后有一个_id元组列表。 我可以四舍五入到最接近的整数百分比。 似乎每次插入某项或插入所有内容然后折叠集之后,都需要检查每个perc_identity中每个元组中_id的存在。 在这种情况下,检索到特定_id所有匹配项似乎效率很低。

或者,由于顺序无关紧要,例如:

{
    _id: ?
    type: 'hit'
    pair1: geneA
    pair2: geneB
    perc_identity: 92
},
{
    _id: ??
    type:'hit'
    pair1: geneC
    pair2: geneA
    perc_identity: 70
},
# etc

对于这些策略之一的任何批评,或对其他表示方法的建议,将不胜感激。 让我知道我是否应该提供其他信息,或者是否可以澄清任何信息。 如果(1)或(2)似乎是好的策略,我想我唯一的问题是基于一些perc_identity阈值构造查询的最佳方法。

这绝不是一个容易回答的问题! 但是,指导原则应该是根据您打算使用数据的方式进行决策。 在这种情况下,您提到了两个查询:

  1. perc_identity > 95抓取所有对
  2. 获得一个基因的所有匹配项

(当然,您可能还打算进行其他一些常见的分析,这有助于将其清楚地说明。)

基于此,我鼓励您采用非规范化方法,如您在第三种替代方法中讨论的方法。 它确实有一些缺点,主要是关于插入,您似乎已经意识到,但是它使第一种查询非常容易:

db.hits.find({perc_identity: {$gt: 95}})

...而采用任何其他方法,您都需要遍历其他文档中的所有键。 例如,使用第一种方法,您需要检索每个基因的hits子文档,遍历这些子文档的键,然后将大于95的那些添加到您的列表中。这需要在mongodb /中完成pymongo。

另一个查询比方法1和2更复杂,但相差不大:

db.hits.find({$or: [{pair1: <your gene>}, {pair2: <your gene>}]})

因此,以插入时更多的逻辑为代价,您提到的两个查询案例变得非常简单,并且数据库服务器本身可以轻松地处理它们。 如果您还有其他常见用例,而用第三种方法很难实现,那么就值得重新研究一下,但是就目前而言,这就是我的选择。

有两个注意事项:首先,MongoDB的文档对数据建模一些很好的建议 ,可能值得阅读。 其次,就我对MongoDB的喜爱程度而言,就我对您的问题域所知甚少,这可能是关系数据库更适合的一种情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM