Mongoose在字段和模式级别都有索引

时间:2015-05-22 20:39:49

标签: mongodb mongoose

据我所知,如果正确实施,索引可以成为快速检索数据的有用工具。我希望能够扫描我的文档以获取某个字段值字段值的组合。

我将索引两个字段(类别,标签)。 Category是一个字符串,tags是一个数组。我需要能够查询特定类别中的项目和/或包含特定标记的项目。

以下是三个例子:

  1. 向我展示该类别中的所有文件:"汽车"
  2. 向我展示包含标签的所有文件:" electric"
  3. 告诉我"汽车"中的所有文件。包含" electric"的类别标签
  4. 这两个字段的模式级索引是否足以满足所有三种情况?

    docSchema.index({category:1, tags:1});
    

    或者我是否还需要在字段级别定义它们,以便在我仅搜索单个字段时支持方案?

    docSchema = mongoose.Schema({
        category: {
            type: String,
            index: true
        },
        tags: {
            type: [String],
            index: true
        }
    });
    

2 个答案:

答案 0 :(得分:2)

您需要category上的single field indextags上的multikey index。您可能想要使用复合索引而不是其中之一。但是如果你使用的是MongoDB> = 2.6则不是强制性的,因为它有一个很好的功能叫index intersection

  
      
  1. 向我展示该类别中的所有文件:“cars”
  2.   
  3. 显示包含标签的所有文件:“electric”
  4.   
  5. 显示“汽车”类别中包含“电子”标签的所有文件
  6.   

(1)将使用category上的索引(包括任何以category作为前缀的索引) (2)将使用tags上的索引(包括任何以tags作为前缀的索引) (3)将使用tags 上的索引或 category 上的索引或 索引交叉点它们(取决于查询规划器的选择)。

作为参考,有一个很好的discussion about index intersection in the MongoDB blog。值得一读整篇文章。但引用结论,主要是将指数交叉点与复合指数进行比较:

  

要明确的是,复合索引总是比索引交集更高性能如果您知道要查询的内容并且可以提前创建一个。此外,如果您的工作集完全在内存中,那么您将无法获得Index Intersection的任何好处,因为它主要基于减少IO。但是在一个更加特殊的情况下,人们无法预测查询的形状并且工作集比可用内存大得多,索引交集会自动接管并选择性能最高的路径。

答案 1 :(得分:2)

docSchema.index({category:1, tags:1});是一个复合索引。

此复合索引支持方案1和3:

- >向我展示该类别中的所有文件:"汽车"

- >向我展示"汽车"中的所有文件。包含" electric"的类别标签

要支持方案2,您需要在tag字段中定义其他单个索引。 docSchema.index({tags:1});

复合索引支持涉及复合索引中所有字段的查询以及涉及复合索引的前缀的查询。在这种情况下,您的复合索引支持涉及类别和标记的查询以及仅涉及类别的查询。

为了更好地理解逻辑,请查看MongoDB文档站点上的Compound Indexes文章。请特别注意讨论前缀

的部分