按标签搜索效率如何?

man*_*dos 5 mongoose

情况:

我有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元素而不必事先将它们全部匹配?

我试图了解这个过程的效率如何,以及我是否能以某种方式改进它.你有什么建议吗?

dre*_*rew 2

是的,它首先匹配 500,000 个条目。

\n\n

来自 MongoDB 权威指南第二版:

\n\n
\n

$skip 接受一个数字 n,并丢弃结果集中的前 n 个文档。与 \xe2\x80\x9cnormal\xe2\x80\x9d 查询一样,对于大型跳过来说,\xe2\x80\x99 效率不高,因为它必须找到所有必须跳过的匹配项,然后丢弃它们。

\n
\n\n

您可以使用explain()从Mongo shell详细检查您的查询:

\n\n

https://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    }\n
Run Code Online (Sandbox Code Playgroud)\n\n

然后解释一下

\n\n
db.people.find({"tags" : "cats"}).skip(100).limit(10).explain("executionStats\xe2\x80\x9d)\n
Run Code Online (Sandbox Code Playgroud)\n\n

TotalDocsExamined 向您显示它正在匹配它正在跳过的所有内容

\n\n
"executionStats" : {\n...\n    "totalDocsExamined" : 420\n
Run Code Online (Sandbox Code Playgroud)\n\n

如果您要在标签上创建索引:

\n\n
db.people.ensureIndex({ "tags" : 1 })\n
Run Code Online (Sandbox Code Playgroud)\n\n

再次运行你会得到:

\n\n
"executionStats" : {\n...\n    "totalDocsExamined" : 110\n
Run Code Online (Sandbox Code Playgroud)\n