代码之家  ›  专栏  ›  技术社区  ›  manidos

按标签搜索的效率如何?

  •  5
  • manidos  · 技术社区  · 8 年前

    我有一百万用户,我想通过标签搜索他们。

    以下是模式:

    const Account = new Schema({
      tags: { type: [String], default: ['cats'] }
    })
    

    第一个问题是:

    const query = { tags: 'cats'}
    const fields = { _id: 0 }
    const options = { skip: 0, limit: 5 }
    
    Account.find(query, fields, options)
    

    通话后 find Mongoose

    下面是第二个问题:

    const query = { tags: 'cats'}
    const fields = { _id: 0 }
    const options = { skip: 500 000, limit: 5 }
    
    Account.find(query, fields, options)
    

    猫鼬

    或者它是否以某种方式“跳转”到500000个元素,而不必事先将它们全部匹配?

    我试图了解这个过程有多高效,以及我是否可以以某种方式改进它。你有什么建议吗?

    2 回复  |  直到 8 年前
        1
  •  3
  •   Soumyajyoti Bhattacharya    8 年前

    有趣的我的理解是 Find Select ,在跳过500000个值之前,它将首先遍历这些值,从而导致效率低下。

    实现这一点应该不会太困难,并且应该大大提高正在进行的遍历量。希望这有帮助。

        2
  •  2
  •   drew    8 年前

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

    $skip取一个数字n,并从结果集中丢弃前n个文档。与普通查询一样,它对于大的跳过并不有效,因为它必须找到所有必须跳过的匹配项,然后丢弃它们。

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

    https://docs.mongodb.com/manual/reference/method/cursor.explain/

    前任:

    // Create a dummy collection
    var tagTypes = ['cats', 'dogs', 'chickens']
        for (i=0; i < 1000; i++) {
            let tag = tagTypes[Math.floor(Math.random()*tagTypes.length)]
            db.people.insert({"tags" : [tag]})
        }
    

    db.people.find({"tags" : "cats"}).skip(100).limit(10).explain("executionStats”)
    

    totalDocsExamined向您展示了它正在匹配它跳过的所有内容

    "executionStats" : {
    ...
        "totalDocsExamined" : 420
    

    如果要在标记上创建索引:

    db.people.ensureIndex({ "tags" : 1 })
    

    再次运行它,您将获得:

    "executionStats" : {
    ...
        "totalDocsExamined" : 110