我们是Mongodb的新手,我们希望用它插入基因组数据(1.65亿个条目),并通过基因组坐标(范围)检索这些数据。下面是存储在单个表中的数据类型。其中列名为chrom,chromStart,chromEnd,datasetid,target,biotype
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基因组范围查询的类型如下:
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()从长远来看,我们计划对范围进行查询,但也对以下值进行查询:
db.hsap_all_peaks.find({ chrom: "chr4", chromStart: {$gte: 950013}, chromEnd:{$lte: 950693}} , target: "KDM1A").pretty()我们是这样为坐标创建索引的:
db.hsap_all_peaks.createIndex(
{chrom:1}
)
db.hsap_all_peaks.createIndex(
{chrom:1,chromStart:1,chromEnd:1}
)但是,查询要执行的时间很长,而且chromStart、chromEnd的索引似乎不起作用。
,因此我的问题:在这里创建索引的最好方法是什么?
额外信息:
> 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表”:
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()输出:
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
}发布于 2021-04-29 18:42:29
概括地说,索引中没有什么需要改进的。您已经有了一个最支持您的查询,而mongo实际上使用它。
提高性能是一个更通用的主题,对SO格式来说可能太宽泛了。
在这种特殊情况下,如果我们可以假设chromStart总是小于chromEnd,我们可以通过添加chromStart的上限(与chromEnd的下限相同)来修改查询:
db.hsap_all_peaks.find({
chrom: "chr1",
chromStart: {$gte: 9905, $lte: 10243},
chromEnd:{$lte: 10243}
} )它将更改explain()中的范围
"indexBounds" : {
"chrom" : [
"[\"chr2\", \"chr2\"]"
],
"chromStart" : [
"[9905.0, inf.0]"
],
"chromEnd" : [
"[-inf.0, 10243.0]"
]
}至
"indexBounds" : {
"chrom" : [
"[\"chr2\", \"chr2\"]"
],
"chromStart" : [
"[9905.0, 10243.0]"
],
"chromEnd" : [
"[-inf.0, 10243.0]"
]
}chromStart范围越小,索引中需要检查的节点就越少。
发布于 2021-05-01 08:45:20
索引的目的是减少处理查询时必须检查的数据量。
使用现有的索引和查询,您可以避免查看与查询不匹配的任何文档。
唯一可能的改进是减少所检查的索引键的数量。
单神扫描索引的方式从$lte运算符的负无穷大开始,对于$gte运算符扩展到正无穷大。
对于任何单个文档,示例数据似乎都具有chromStart严格小于chromEnd的属性。
如果这个假设是正确的,那么可以通过限制限制来更好地优化查询。
考虑一下您解释的查询:
db.hsap_all_peaks.find({
chrom: "chr2",
chromStart: {$gte: 50967094},
chromEnd:{$lte: 50970983}
})正如explain命令所报告的,获胜计划使用索引界限:
"indexBounds" : {
"chrom" : [ "[\"chr2\", \"chr2\"]" ],
"chromStart" : ["[50967094.0, inf.0]"],
"chromEnd" : ["[-inf.0, 50970983.0]"]
}这些inf.0意味着无穷大,对于不匹配的文档,这可能是相当多的键。
如果要对查询中的两个条件同时使用这两个值,如下所示:
db.hsap_all_peaks.find({
chrom: "chr2",
chromStart: {$gte: 50967094, $lte: 50970983},
chromEnd:{$gte: 50967094, $lte: 50970983}
})这些索引界限可以(理论上)减少到:
"indexBounds" : {
"chrom" : [ "[\"chr2\", \"chr2\"]" ],
"chromStart" : ["[50967094.0, 50970983.0]"],
"chromEnd" : ["[50967094.0, 50970983.0]"]
}在一个非常大的数据集中,这可能是数以百万计的不再需要计算的键。
或者完全是浪费时间。
我很想知道这是否真的有帮助。
https://stackoverflow.com/questions/67313674
复制相似问题