情况:
我有100万用户,我想通过标签搜索它们.
这是架构:
const Account = new Schema({
tags: { type: [String], default: ['cats'] }
})
Run Code Online (Sandbox Code Playgroud)
这是第一个查询:
const query = { tags: 'cats'}
const fields = { _id: 0 }
const options = { skip: 0, limit: 5 }
Account.find(query, fields, options)
Run Code Online (Sandbox Code Playgroud)
调用find方法后,Mongoose将开始搜索并返回它匹配的前5个条目.在这种情况下的表现是最佳的.
这是第二个查询:
const query = { tags: 'cats'}
const fields = { _id: 0 }
const options = { skip: 500 000, limit: 5 }
Account.find(query, fields, options)
Run Code Online (Sandbox Code Playgroud)
在这种情况下发生的事情是我感兴趣的.
并Mongoose首先匹配500个000项,然后返回未来5项?
或者它是否以某种方式"跳"到500 000元素而不必事先将它们全部匹配?
我试图了解这个过程的效率如何,以及我是否能以某种方式改进它.你有什么建议吗?
是的,它首先匹配 500,000 个条目。
\n\n来自 MongoDB 权威指南第二版:
\n\n\n\n\n$skip 接受一个数字 n,并丢弃结果集中的前 n 个文档。与 \xe2\x80\x9cnormal\xe2\x80\x9d 查询一样,对于大型跳过来说,\xe2\x80\x99 效率不高,因为它必须找到所有必须跳过的匹配项,然后丢弃它们。
\n
您可以使用explain()从Mongo shell详细检查您的查询:
\n\nhttps://docs.mongodb.com/manual/reference/method/cursor.explain/
\n\n前任:
\n\n// Create a dummy collection\nvar tagTypes = [\'cats\', \'dogs\', \'chickens\']\n for (i=0; i < 1000; i++) {\n let tag = tagTypes[Math.floor(Math.random()*tagTypes.length)]\n db.people.insert({"tags" : [tag]})\n }\nRun Code Online (Sandbox Code Playgroud)\n\n然后解释一下
\n\ndb.people.find({"tags" : "cats"}).skip(100).limit(10).explain("executionStats\xe2\x80\x9d)\nRun Code Online (Sandbox Code Playgroud)\n\nTotalDocsExamined 向您显示它正在匹配它正在跳过的所有内容
\n\n"executionStats" : {\n...\n "totalDocsExamined" : 420\nRun Code Online (Sandbox Code Playgroud)\n\n如果您要在标签上创建索引:
\n\ndb.people.ensureIndex({ "tags" : 1 })\nRun Code Online (Sandbox Code Playgroud)\n\n再次运行你会得到:
\n\n"executionStats" : {\n...\n "totalDocsExamined" : 110\nRun Code Online (Sandbox Code Playgroud)\n
| 归档时间: |
|
| 查看次数: |
216 次 |
| 最近记录: |