【问题标题】:MongoDB query by one index, sort by antoherMongoDB按一个索引查询,按另一个排序
【发布时间】:2015-11-18 16:45:26
【问题描述】:

我收藏的文档的相关字段如下:

{
  point: {
    type: Point,
    coordinates: [15.6446464, 45.231323]
  }
  score: 24
}

我在point 上有一个2dsphere 索引,在score 上有一个“正常”的降序索引。 我想运行以下查询:

db.properties.find({point: {$geoWithin: <some polygon> }}).sort({score: -1}).limit(2000)

有什么方法可以让 mongo 使用point 上的索引作为find 部分,然后使用score 上的索引进行排序?

该集合有大约 700k 个文档,find 部分可以返回数万个文档,每个文档最多有一个 MB。

当前的问题是,当使用point 索引时,返回的集合的大小太大,无法在内存中排序。使用score 索引时,查询太慢,因为是对坐标进行顺序扫描。

【问题讨论】:

    标签: mongodb


    【解决方案1】:

    执行当前查询时,MongoDB 将仅使用point 上的索引。运行find 后,您将拥有数据的一个子集,因此Mongo 不能再使用score 上的索引。您可以改为在pointscore 上创建一个复合索引,其中score 按降序索引。尽管第一个值是唯一的,但它有助于加快排序速度,因为 MongoDB 可以使用索引对 score 进行排序,而不必扫描整个文档(最大可达 MB 大小)。

    复合索引在编制索引时遵循一般经验法则。一般来说,索引的顺序应该是:

    1. 您将查询确切值的字段。
    2. 您要排序的字段。
    3. 您将在其上查询一系列值的字段。

    但是,根据您的评论,此复合索引不是很快,这表明 MongoDB 无法将整个索引加载到内存中。您为 MongoDB 分配了多少 RAM?你有机会增加这个吗?

    【讨论】:

    • 我试过做一个复合索引,但这对我没有帮助,因为point 几乎对每个文档都是唯一的,所以scores 在技术上是随机的。
    • 您是说使用索引对数据子集进行排序在技术上不可行吗?我有这种感觉,但我找不到解释。
    • 不,您不能对数据子集使用单独的索引。关于复合键,你测试过吗?我希望复合键在这种情况下是最快的。
    • 是的,我有,排序真的很慢。删除排序后,速度很快。但我看不出复合索引在其第一个字段的值是唯一的时有什么帮助 - scores 无法在这样的索引中排序。
    • 查看我的更新答案,您可以为您的 MongoDB 实例分配更多 RAM 吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-14
    • 1970-01-01
    • 2020-10-16
    相关资源
    最近更新 更多