【问题标题】:MongoDB - Query not working in 2.6MongoDB - 查询在 2.6 中不起作用
【发布时间】:2014-11-12 17:41:38
【问题描述】:

我目前正在将我们的数据库从 Mongo 2.4.9 迁移到 2.6.4。

我有一个奇怪的情况,即在 2.4 中给出良好结果的查询在 2.6 中没有返回任何文档。

有问题的查询:

var dbSearch = {
    created: { $gte: new Date(1409815194808) },
    geolocation: {
        $geoWithin: {
            $center: [ [ 4.895167900000001, 52.3702157 ], 0.1125 ]
        }
    }
};

在该集合上有以下(相关)索引:

{ "v" : 1, "key" : { "created" : -1 }, "name" : "createdIndex", "ns" : "prod.search", "background" : true }
{ "v" : 1, "key" : { "geolocation" : "2d", "created" : -1 }, "name" : "geolocationCreatedIndex", "ns" : "prod.search" }

对 Mongo 2.6 运行此查询会得到以下查询日志:

{ created: { $gte: new Date(1409815194808) }, geolocation: { $geoWithin: { $center: [ [ 4.895167900000001, 52.3702157 ], 0.1125 ] } } } 
planSummary: IXSCAN { created: -1 } ntoreturn:0 ntoskip:0 keyUpdates:0 numYields:0 locks(micros) r:8196 nreturned:0 reslen:20 8ms

我正在使用 NodeJS 使用 node-mongodb-native 模块将此查询发送到数据库。

请注意,当我删除任一搜索字段(createdgeolocation)时,查询将在 2.4 和 2.6 上产生正确的结果。组合(如上所示)在 2.6 上没有结果

使用额外要求的信息进行编辑

解释 mongo 2.4 查询:

> db.search.find({created: { $gte: new Date(1409815194808) }, geolocation: {$geoWithin: {$center: [ [ 4.895167900000001, 52.3702157 ], 0.1125 ] } } }).explain()
{
    "cursor" : "GeoBrowse-circle",
    "isMultiKey" : false,
    "n" : 321,
    "nscannedObjects" : 321,
    "nscanned" : 321,
    "nscannedObjectsAllPlans" : 321,
    "nscannedAllPlans" : 321,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 0,
    "nChunkSkips" : 0,
    "millis" : 69,
    "indexBounds" : {
        "geolocation" : [ ]
    },
    "lookedAt" : NumberLong(8940),
    "matchesPerfd" : NumberLong(8538),
    "objectsLoaded" : NumberLong(8538),
    "pointsLoaded" : NumberLong(0),
    "pointsSavedForYield" : NumberLong(0),
    "pointsChangedOnYield" : NumberLong(0),
    "pointsRemovedOnYield" : NumberLong(0),
    "server" : "ubmongo24.local:27017"
}

解释 mongo 2.6 查询:

> db.search.find({created: { $gte: new Date(1409815194808) }, geolocation: {$geoWithin: {$center: [ [ 4.895167900000001, 52.3702157 ], 0.1125 ] } } }).explain();
{
    "cursor" : "BtreeCursor createdIndex",
    "isMultiKey" : false,
    "n" : 0,
    "nscannedObjects" : 1403,
    "nscanned" : 1403,
    "nscannedObjectsAllPlans" : 2808,
    "nscannedAllPlans" : 2808,
    "scanAndOrder" : false,
    "indexOnly" : false,
    "nYields" : 21,
    "nChunkSkips" : 0,
    "millis" : 8,
    "indexBounds" : {
        "created" : [
            [
                ISODate("0NaN-NaN-NaNTNaN:NaN:NaNZ"),
                ISODate("2014-09-04T07:19:54.808Z")
            ]
        ]
    },
    "server" : "ubmongo26.local:27017",
    "filterSet" : false
}

【问题讨论】:

  • 你有最新的node mongo驱动吗?
  • 您能否解释一下 2.4 和 2.6 并将结果添加到问题中 - 仅供参考,2.6 中的复合地理索引存在一个未解决的问题:jira.mongodb.org/browse/SERVER-14264 但与您报告的不完全相同结果
  • @AdamComerford 我在帖子中添加了解释信息。您提到的项目看起来可能是相关的。
  • @joao 是的,我用的是node-mongodb-native 1.4.12,根据github应该是最新的

标签: mongodb mongodb-query


【解决方案1】:

根据解释输出,问题似乎是查询优化器选择的索引(在 2.6 中进行了大修——主要是为了更好,但这确实意味着存在新的边缘情况)。它使用单个字段 createdIndex 而不是 2.4 中使用的复合索引

尝试在 2.6 (.hint({ "geolocation" : "2d", "created" : -1 })) 中提示 geolocationCreatedIndex 索引,看看是否能解决您的问题 - 它默认选择 createdIndex,因此根本不使用地理索引。

【讨论】:

  • 感谢您的回答,在此案例中使用 $hint 可以得到正确的结果。然而,这让我在这一点上转移到 Mongo 2.6 有点犹豫,因为我觉得“选择要使用的正确索引”是一个非常重要的数据库功能,我现在不愿意相信它。您能否就从这里的前进方向提出建议:-我应该将此作为错误报告给 MongoDB 吗? - 我真的需要检查所有查询是否正确使用索引吗? - 我可以使用索引“最佳实践”来增加 2.6 选择正确索引的机会吗?谢谢
  • 这很难确定,可能需要内核工程师来权衡,所以 Jira 问题意味着他们需要看看。解释一下,我认为优化器可能正在做“正确”的事情——从技术上讲,$geowithin 不需要地理索引,我打赌创建的索引首先返回最初的 101 个文档,因此由优化器选择。提示或使用过滤器 (docs.mongodb.org/manual/core/query-plans/#index-filters) 将在此期间解决它,但一般来说,为此类查询调整优化器可能是值得的
猜你喜欢
  • 1970-01-01
  • 2014-11-21
  • 2012-06-09
  • 2016-03-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多