xbu*_*gos 6 mongodb mongodb-query spring-data-mongodb
我正在开发一个使用 Solr 进行全文搜索和使用 Mongodb 作为持久存储的项目。基本上在 Solr 中搜索返回 Mongo id,然后我们用它来获取文档。
问题在于,某些 Solr 搜索会以数千个 Id 的顺序返回结果。这些结果实际上是我们所期望的,所以这里的 Solr 没有问题。当我们想从 mongodb 获取 10k Id 时,问题就出现了。查询正在使用 $in 但花费的时间太长;检查mongodb profiler后,似乎mongo花了很多时间等待获取读锁。
任何替代方法?,也许仍在使用 $in 但将 Id 集拆分为更小的块?。
作为旁注,我们使用的是 Java 8、Spring 4.0 和 Spring-Data-Mongo 1.6
此外,作为附加信息,该集合有 130 万个文档,每个文档的平均大小为 11Kb。
这是查询的示例:
{"_id" : {
"$in" : [
ObjectId("5441614a5d28a9872823694c"),
ObjectId("544155eb5d28a987281aa112"),
ObjectId("5441500e5d28a9872815b917"),
ObjectId("544153285d28a987281877b9"),
ObjectId("544159095d28a987281c1f5c"),
ObjectId("54415b105d28a987281d3ad7"),
ObjectId("54415a995d28a987281cf0e6"),
ObjectId("544160215d28a9872822383b"),
ObjectId("544160e85d28a98728230342"),
ObjectId("544157ba5d28a987281b7dea"),
ObjectId("54415e375d28a9872820508b"),
ObjectId("544150f75d28a98728169563"),
ObjectId("54415c6b5d28a987281e8bcb"),
ObjectId("54415a6d5d28a987281cd704").............]}}
Run Code Online (Sandbox Code Playgroud)
这是一个小集合的解释结果:
{
"cursor" : "BtreeCursor _id_ multi",
"isMultiKey" : false,
"n" : 14,
"nscannedObjects" : 14,
"nscanned" : 27,
"nscannedObjectsAllPlans" : 14,
"nscannedAllPlans" : 27,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"_id" : [
[
ObjectId("5441500e5d28a9872815b917"),
ObjectId("5441500e5d28a9872815b917")
],
[
ObjectId("544150f75d28a98728169563"),
ObjectId("544150f75d28a98728169563")
],
[
ObjectId("544153285d28a987281877b9"),
ObjectId("544153285d28a987281877b9")
],
[
ObjectId("544155eb5d28a987281aa112"),
ObjectId("544155eb5d28a987281aa112")
],
[
ObjectId("544157ba5d28a987281b7dea"),
ObjectId("544157ba5d28a987281b7dea")
],
[
ObjectId("544159095d28a987281c1f5c"),
ObjectId("544159095d28a987281c1f5c")
],
[
ObjectId("54415a6d5d28a987281cd704"),
ObjectId("54415a6d5d28a987281cd704")
],
[
ObjectId("54415a995d28a987281cf0e6"),
ObjectId("54415a995d28a987281cf0e6")
],
[
ObjectId("54415b105d28a987281d3ad7"),
ObjectId("54415b105d28a987281d3ad7")
],
[
ObjectId("54415c6b5d28a987281e8bcb"),
ObjectId("54415c6b5d28a987281e8bcb")
],
[
ObjectId("54415e375d28a9872820508b"),
ObjectId("54415e375d28a9872820508b")
],
[
ObjectId("544160215d28a9872822383b"),
ObjectId("544160215d28a9872822383b")
],
[
ObjectId("544160e85d28a98728230342"),
ObjectId("544160e85d28a98728230342")
],
[
ObjectId("5441614a5d28a9872823694c"),
ObjectId("5441614a5d28a9872823694c")
]
]
},
"server" : "0001a22df018:27017"
Run Code Online (Sandbox Code Playgroud)
}
也许这些信息可以提供帮助,仅供参考。
集合大小大于1.3M x 11K = 14.6GB(不算小)
想要查询的文档率是10K / 1.3M = 0.75%
这些文档都已建立索引,查找任何文档都应该非常快。但收藏量很大。由于您没有提供有关 id 的信息,那么我只是认为这些 id 的文档分布几乎是任意的。
首先,MongoDB 可能会尝试从内存中查找所有文档。当找不到更多的数据时,它会根据剩余的id从磁盘加载新的数据到内存中,并再次重复搜索,直到最后完成工作。从磁盘加载的时间可能是决定查询性能的主要因素。加载时间取决于你的 ids 的分布。如果它们分布非常密集,则查询应该非常快,否则可能会很慢。因此,速度取决于您正在搜索的文档的分布。
使用分片集合(更多分片实例)可能会提供一些帮助。