首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Mongodb为基因组范围创建索引

Mongodb为基因组范围创建索引
EN

Stack Overflow用户
提问于 2021-04-29 08:25:09
回答 2查看 70关注 0票数 1

我们是Mongodb的新手,我们希望用它插入基因组数据(1.65亿个条目),并通过基因组坐标(范围)检索这些数据。下面是存储在单个表中的数据类型。其中列名为chrom,chromStart,chromEnd,datasetid,target,biotype

代码语言:javascript
复制
chr1 9903 10282 ENCSR440COG ZNF239 HEK293
chr1 9904 10252 ENCSR721QZV ZSCAN18 HEK293
chr1 9905 10132 ENCSR241LIH AFF1 K-562
chr1 9905 10238 ENCSR211GNP ZSCAN4 HEK293
chr1 9905 10241 ENCSR776LDJ ZNF645 HEK293
chr1 9905 10243 ENCSR042TWZ SNIP1 MCF-7
chr2 938173 938703 ENCSR000BUL MAX MCF-7
chr2 938174 938376 ENCSR108TYQ GATAD1 Hep-G2
chr3 938174 938412 ENCSR887MXT ZHX1 HeLa-S3
chr3 945236 945377 GSE46055 KDM5B SUM185_SHCTCF
chr4 945236 945488 ENCSR000BPU ETS1 A-549
chr4 945240 945501 GSE76494 CTCF HEK293
chr4 950008 951114 GSE67783 STAG1 HSPC
chr4 950013 950185 ENCSR000BQT TCF3 GM12878
chr4 950015 950797 ENCSR115BLD KDM1A Hep-G2
chr4 950024 950693 GSE88734 ZEB1 MIA-PaCa-2
chr4 950028 950565 ENCSR753GIA TARDBP HEK293T

基因组范围查询的类型如下:

代码语言:javascript
复制
db.hsap_all_peaks.find({ chrom: "chr1",  chromStart: {$gte: 9905}, chromEnd:{$lte: 10243}} ).count()
db.hsap_all_peaks.find({ chrom: "chr4",  chromStart: {$gte: 950013}, chromEnd:{$lte: 950693}} ).pretty()

从长远来看,我们计划对范围进行查询,但也对以下值进行查询:

代码语言:javascript
复制
db.hsap_all_peaks.find({ chrom: "chr4",  chromStart: {$gte: 950013}, chromEnd:{$lte: 950693}} , target: "KDM1A").pretty()

我们是这样为坐标创建索引的:

代码语言:javascript
复制
db.hsap_all_peaks.createIndex(
    {chrom:1}
)
db.hsap_all_peaks.createIndex(
    {chrom:1,chromStart:1,chromEnd:1}
)

但是,查询要执行的时间很长,而且chromStartchromEnd的索引似乎不起作用。

,因此我的问题:在这里创建索引的最好方法是什么?

额外信息:

代码语言:javascript
复制
> db.hsap_all_peaks.getIndexes()
[
    {
        "v" : 2,
        "key" : {
            "_id" : 1
        },
        "name" : "_id_"
    },
    {
        "v" : 2,
        "key" : {
            "chrom" : 1,
            "chromStart" : 1,
            "chromEnd" : 1
        },
        "name" : "chrom_1_chromStart_1_chromEnd_1"
    },
    {
        "v" : 2,
        "key" : {
            "chrom" : 1
        },
        "name" : "chrom_1"
    }
]

如果您想要重新创建一个类似的“‘ish表”:

代码语言:javascript
复制
wget http://remap.univ-amu.fr/storage/remap2020/hg38/MACS2/remap2020_all_macs2_hg38_v1_0.bed.gz
gunzip remap2020_all_macs2_hg38_v1_0.bed.gz
mongoimport -d databaseName -c hsap_all_peaks --type tsv --file remap2020_all_macs2_hg38_v1_0.bed -f chrom,chromStart,chromEnd,name,score,strand,thickStart,thickEnd,itemRgb  --numInsertionWorkers 2

经典查询的Explain()输出:

代码语言:javascript
复制
db.hsap_all_peaks.find({ chrom: "chr2",  chromStart: {$gte: 50967094}, chromEnd:{$lte: 50970983} }  ).explain()
{
    "queryPlanner" : {
        "plannerVersion" : 1,
        "namespace" : "remap2020.hsap_all_peaks",
        "indexFilterSet" : false,
        "parsedQuery" : {
            "$and" : [
                {
                    "chrom" : {
                        "$eq" : "chr2"
                    }
                },
                {
                    "chromEnd" : {
                        "$lte" : 50970983
                    }
                },
                {
                    "chromStart" : {
                        "$gte" : 50967094
                    }
                }
            ]
        },
        "queryHash" : "2A452369",
        "planCacheKey" : "C93EF492",
        "winningPlan" : {
            "stage" : "FETCH",
            "inputStage" : {
                "stage" : "IXSCAN",
                "keyPattern" : {
                    "chrom" : 1,
                    "chromStart" : 1,
                    "chromEnd" : 1
                },
                "indexName" : "chrom_1_chromStart_1_chromEnd_1",
                "isMultiKey" : false,
                "multiKeyPaths" : {
                    "chrom" : [ ],
                    "chromStart" : [ ],
                    "chromEnd" : [ ]
                },
                "isUnique" : false,
                "isSparse" : false,
                "isPartial" : false,
                "indexVersion" : 2,
                "direction" : "forward",
                "indexBounds" : {
                    "chrom" : [
                        "[\"chr2\", \"chr2\"]"
                    ],
                    "chromStart" : [
                        "[50967094.0, inf.0]"
                    ],
                    "chromEnd" : [
                        "[-inf.0, 50970983.0]"
                    ]
                }
            }
        },
        "rejectedPlans" : [
            {
                "stage" : "FETCH",
                "filter" : {
                    "$and" : [
                        {
                            "chromEnd" : {
                                "$lte" : 50970983
                            }
                        },
                        {
                            "chromStart" : {
                                "$gte" : 50967094
                            }
                        }
                    ]
                },
                "inputStage" : {
                    "stage" : "IXSCAN",
                    "keyPattern" : {
                        "chrom" : 1
                    },
                    "indexName" : "chrom_1",
                    "isMultiKey" : false,
                    "multiKeyPaths" : {
                        "chrom" : [ ]
                    },
                    "isUnique" : false,
                    "isSparse" : false,
                    "isPartial" : false,
                    "indexVersion" : 2,
                    "direction" : "forward",
                    "indexBounds" : {
                        "chrom" : [
                            "[\"chr2\", \"chr2\"]"
                        ]
                    }
                }
            }
        ]
    },
    "serverInfo" : {
        "host" : "sormiou.local",
        "port" : 27017,
        "version" : "4.4.3",
        "gitVersion" : "913d6b62acfbb344dde1b116f4161360acd8fd13"
    },
    "ok" : 1
}
EN

回答 2

Stack Overflow用户

发布于 2021-04-29 18:42:29

概括地说,索引中没有什么需要改进的。您已经有了一个最支持您的查询,而mongo实际上使用它。

提高性能是一个更通用的主题,对SO格式来说可能太宽泛了。

在这种特殊情况下,如果我们可以假设chromStart总是小于chromEnd,我们可以通过添加chromStart的上限(与chromEnd的下限相同)来修改查询:

代码语言:javascript
复制
db.hsap_all_peaks.find({ 
    chrom: "chr1",  
    chromStart: {$gte: 9905, $lte: 10243}, 
    chromEnd:{$lte: 10243}
} )

它将更改explain()中的范围

代码语言:javascript
复制
            "indexBounds" : {
                "chrom" : [
                    "[\"chr2\", \"chr2\"]"
                ],
                "chromStart" : [
                    "[9905.0, inf.0]"
                ],
                "chromEnd" : [
                    "[-inf.0, 10243.0]"
                ]
            }

代码语言:javascript
复制
            "indexBounds" : {
                "chrom" : [
                    "[\"chr2\", \"chr2\"]"
                ],
                "chromStart" : [
                    "[9905.0, 10243.0]"
                ],
                "chromEnd" : [
                    "[-inf.0, 10243.0]"
                ]
            }

chromStart范围越小,索引中需要检查的节点就越少。

票数 0
EN

Stack Overflow用户

发布于 2021-05-01 08:45:20

索引的目的是减少处理查询时必须检查的数据量。

使用现有的索引和查询,您可以避免查看与查询不匹配的任何文档。

唯一可能的改进是减少所检查的索引键的数量。

单神扫描索引的方式从$lte运算符的负无穷大开始,对于$gte运算符扩展到正无穷大。

对于任何单个文档,示例数据似乎都具有chromStart严格小于chromEnd的属性。

如果这个假设是正确的,那么可以通过限制限制来更好地优化查询。

考虑一下您解释的查询:

代码语言:javascript
复制
db.hsap_all_peaks.find({ 
              chrom: "chr2",  
              chromStart: {$gte: 50967094}, 
              chromEnd:{$lte: 50970983} 
})

正如explain命令所报告的,获胜计划使用索引界限:

代码语言:javascript
复制
 "indexBounds" : {
                    "chrom" : [ "[\"chr2\", \"chr2\"]" ],
                    "chromStart" : ["[50967094.0, inf.0]"],
                    "chromEnd" : ["[-inf.0, 50970983.0]"]
                }

这些inf.0意味着无穷大,对于不匹配的文档,这可能是相当多的键。

如果要对查询中的两个条件同时使用这两个值,如下所示:

代码语言:javascript
复制
db.hsap_all_peaks.find({ 
              chrom: "chr2",  
              chromStart: {$gte: 50967094, $lte: 50970983}, 
              chromEnd:{$gte: 50967094, $lte: 50970983} 
})

这些索引界限可以(理论上)减少到:

代码语言:javascript
复制
 "indexBounds" : {
                    "chrom" : [ "[\"chr2\", \"chr2\"]" ],
                    "chromStart" : ["[50967094.0, 50970983.0]"],
                    "chromEnd" : ["[50967094.0, 50970983.0]"]
                }

在一个非常大的数据集中,这可能是数以百万计的不再需要计算的键。

或者完全是浪费时间。

我很想知道这是否真的有帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/67313674

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档