【问题标题】:How to create tree like compound index in mongodb如何在mongodb中创建树状复合索引
【发布时间】:2013-08-14 23:16:48
【问题描述】:

我是索引新手。只需阅读docs

如何创建如下所示的复合索引。我想在州名上创建一个索引,在该索引内,我想根据该州的人口创建一个索引。

                 state wise index
                       |
 ----------------------------------------------------
 |                    |                              |
pop<2000    pop>2000 & pop<5000    pop>5000 & pop<10000

为@Derick 更新了问题:

这是我的模拟数据。

    {"pop" : 1000,"state" : "AL"}
    {"pop" : 1500,"state" : "AL"}

    {"pop" : 2500,"state" : "AL"}
    {"pop" : 3000,"state" : "AL"}

    {"pop" : 6000,"state" : "AL"}
    {"pop" : 8000,"state" : "CA"}

那么,

db.simplezips.createIndex({state:1, pop:1});
db.simpezips.find({state:"AL", pop:{$gte:2500}}).explain(); 

提供如下日志。这符合我的预期。

    "n" : 3,
    "nscannedObjects" : 3,
    "nscanned" : 3,
    "nscannedObjectsAllPlans" : 3,
    "nscannedAllPlans" : 3,

问题:

  1. 我想知道的是,mongodb 如何对文档进行分桶/索引 基于人口。
  2. 如何自定义分桶? (如上图所示 图表。)

【问题讨论】:

  • 你想用那个来完成什么?
  • @Philipp,通过创建如上所述的索引,我可以减少要扫描的行数。例如。如果查询是 state=="CA" 并且 pop>3000 上面的索引将只扫描落在中间和最后一个桶的文档。但是在没有如上所示的pop索引的情况下,它必须扫描状态索引下的所有文档。

标签: mongodb mongoose


【解决方案1】:

您无法控制 MongoDB 如何存储其索引。而且很可能你不需要。 pop 字段上的简单索引可能就足够了。

但是,当您真的想尝试利用您只有三个要查询的范围这一事实来尝试获得一些额外的性能时,您可以在每个文档中添加另一个字段 sizeCategory,其值为 1当pop 2当pop在2000和5000之间或3当pop大于5000时。在该字段上创建一个非唯一索引并查询它。

【讨论】:

  • 其实,只有 3 个元素的索引不会比正常范围查询快多少,所以我怀疑这是必要的。
【解决方案2】:

你的意思是关于状态的复合索引吗?然后就可以了:

db.collection.ensureIndex( { state: 1, pop: 1 } );

该索引可用于以下查询组:

  • find( { state: "TX", pop: { $lt : 2000 } } )
  • find( { state: "TX", pop: { $gte: 2000, $lt: 5000 } } )
  • find( { state: "TX" } ).sort( { pop: 1 } );
  • find( { state: "TX", pop: { $gte: 2000, $lt: 5000 } } ).sort( { pop: -1 } )

MongoDB 不使用“桶”作为索引,而是使用适用于范围查询的 b 树。您无法控制此机制,但您也不必控制,因为 b 树已经足够好,并且添加特定字段来存储“桶号”的解决方案不太可能提高性能。

【讨论】:

  • 感谢@Derick 的回答。我已经更新了这个问题。请阅读我在问题中的更新。
猜你喜欢
  • 2016-04-17
  • 1970-01-01
  • 2012-07-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-26
  • 2022-01-07
  • 1970-01-01
相关资源
最近更新 更多