我有这样的集合:
{
"_id" : ObjectId("51f4ad560364f5490ccebe26"),
"fiTpcs" : [
"uuid1",
"uuid2",
"uuid3",
"uuid4",
"uuid5"
],
"fiTpcsCnt" : 5
}
Run Code Online (Sandbox Code Playgroud)
fiTpcs列表很长,之后可能会有数百个.当我检索我的收藏时,我希望得到一个有限的fiTpcs列表,一次说20个并发出单独的请求以从fiTpcs获取后续数据.我只想确保稍后当我有更多数据时查询不会变慢.有没有办法在mongodb中做到这一点?直到现在,我一直在做
db.userext.find({"_id" : ObjectId("51f4ad560364f5490ccebe26")}).pretty();
Run Code Online (Sandbox Code Playgroud)
它总能让我获得完整的fiTpcs数组.我在Spring中使用java驱动程序,使用Spring/java的解决方案也没问题.请注意 - 如果解决方案需要mongo扫描整个fiTpcs数组然后切片它的一部分,它并没有真正增加任何性能优势,这不是我想要的.
我可能无法全面了解您的问题,但似乎$slice是您正在寻找的机器人:
> db.page.find()
{ "_id" : ObjectId("51f4ad560364f5490ccebe26"), "fiTpcs" : [ "uuid1", "uuid2", "uuid3", "uuid4", "uuid5" ], "fiTpcsCnt" : 2 }
> db.page.find({}, {"fiTpcs" : {$slice : 3}})
{ "_id" : ObjectId("51f4ad560364f5490ccebe26"), "fiTpcs" : [ "uuid1", "uuid2", "uuid3" ], "fiTpcsCnt" : 2 }
> db.page.find({}, {"fiTpcs" : {$slice : [1,3]}})
{ "_id" : ObjectId("51f4ad560364f5490ccebe26"), "fiTpcs" : [ "uuid2", "uuid3", "uuid4" ], "fiTpcsCnt" : 2 }
Run Code Online (Sandbox Code Playgroud)
经过几天的思考/尝试各种选择,这就是我最终所做的。我这样修改我的文档:
{
"_id" : ObjectId("51f4ad560364f5490ccebe26"),
"page" : 1, //1 is the default
"slug" : "some-unique-string-identifier"
"fiTpcs" : [
"uuid1", //these could be long text, like a long comment/essay
"uuid2",
"uuid3",
"uuid4",
"uuid5"
],
"fiTpcsCnt" : 5
}
Run Code Online (Sandbox Code Playgroud)
我在 memcached 中保留了“pageCount”和“totalFiTpcsCnt”。我已设置 MAX_FITPCSCNT = 500(目前为 500,实验性的)。当我创建 userext 类型的新文档时,我将页面值设置为 1。
如果我必须将一个新对象推送到 fiTpcs 数组:
1) 检查“totalFiTpcsCnt”是否是 500 的倍数。如果是,则创建一个 userext 类型的新文档,具有相同的 slug,fiTpcsCnt 为 0,fiTpcs 数组为 null。2) 更新最后一个 userext - 通过 slug 和“pageCount”查询,推送到 fiTpcs。逐出“pageCount”和“totalFiTpcsCnt”的缓存。
每当我需要 userext 文档时,我总是只获取第一页。这样我就永远不需要一次查询超过 500 个 fiTpcs 类型的对象,并且我仍然可以在 memcached 中始终更新totalFiTpcsCnt。