优化mongodb $并使用$或者查询

时间:2013-11-12 02:21:58

标签: mongodb indexing

我正在尝试优化此查询,但我无法使用索引。仅使用$or查询,$or字段上的3个索引就可以正常工作。但是,如果我在其中添加$and,那么它只使用actor._id索引。

{
  '$and': [
    {
      '$or': [
        {
          'object._id': ObjectId('512fbef8a989b28ddb5cdf93')
        },
        {
          'target._id': ObjectId('512fbef8a989b28ddb5cdf93')
        },
        {
          'target.user_id': ObjectId('512fbef8a989b28ddb5cdf93')
        }
      ]
    },
    {
      'actor._id': {
        '$ne': ObjectId('512fbef8a989b28ddb5cdf93')
      }
    }
  ]
}

有人可以帮我优化此查询或优化索引吗?

提前致谢

这里要求的是每个人的解释结果。

使用And

{
"cursor" : "BtreeCursor actor._id_1 multi",
"isMultiKey" : false,
"n" : 2464,
"nscannedObjects" : 1761201,
"nscanned" : 1761202,
"nscannedObjectsAllPlans" : 1761201,
"nscannedAllPlans" : 1761202,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 3,
"nChunkSkips" : 0,
"millis" : 6215,
"indexBounds" : {
    "actor._id" : [
        [
            {
                "$minElement" : 1
            },
            ObjectId("512fbef8a989b28ddb5cdf93")
        ],
        [
            ObjectId("512fbef8a989b28ddb5cdf93"),
            {
                "$maxElement" : 1
            }
        ]
    ]
},
"server" : "Michaels-MacBook-Pro.local:27017"

}

没有$和

{
"clauses" : [
    {
        "cursor" : "BtreeCursor object._id_1",
        "isMultiKey" : false,
        "n" : 388,
        "nscannedObjects" : 388,
        "nscanned" : 388,
        "nscannedObjectsAllPlans" : 388,
        "nscannedAllPlans" : 388,
        "scanAndOrder" : false,
        "indexOnly" : false,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "millis" : 4,
        "indexBounds" : {
            "object._id" : [
                [
                    ObjectId("512fbef8a989b28ddb5cdf93"),
                    ObjectId("512fbef8a989b28ddb5cdf93")
                ]
            ]
        }
    },
    {
        "cursor" : "BtreeCursor target._id_1",
        "isMultiKey" : false,
        "n" : 77,
        "nscannedObjects" : 375,
        "nscanned" : 375,
        "nscannedObjectsAllPlans" : 375,
        "nscannedAllPlans" : 375,
        "scanAndOrder" : false,
        "indexOnly" : false,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "millis" : 3,
        "indexBounds" : {
            "target._id" : [
                [
                    ObjectId("512fbef8a989b28ddb5cdf93"),
                    ObjectId("512fbef8a989b28ddb5cdf93")
                ]
            ]
        }
    },
    {
        "cursor" : "BtreeCursor target.user_id_1",
        "isMultiKey" : false,
        "n" : 2554,
        "nscannedObjects" : 2554,
        "nscanned" : 2554,
        "nscannedObjectsAllPlans" : 2554,
        "nscannedAllPlans" : 2554,
        "scanAndOrder" : false,
        "indexOnly" : false,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "millis" : 23,
        "indexBounds" : {
            "target.user_id" : [
                [
                    ObjectId("512fbef8a989b28ddb5cdf93"),
                    ObjectId("512fbef8a989b28ddb5cdf93")
                ]
            ]
        }
    }
],
"n" : 3019,
"nscannedObjects" : 3317,
"nscanned" : 3317,
"nscannedObjectsAllPlans" : 3317,
"nscannedAllPlans" : 3317,
"millis" : 31,
"server" : "Michaels-MacBook-Pro.local:27017"

}

1 个答案:

答案 0 :(得分:1)

我不明白为什么你需要这个$和

{
  '$and': [{
      '$or': [
        {'object._id': ObjectId('512fbef8a989b28ddb5cdf93')},
        {'target._id': ObjectId('512fbef8a989b28ddb5cdf93')},
        {'target.user_id': ObjectId('512fbef8a989b28ddb5cdf93')}
      ]
    },{
      'actor._id': {'$ne': ObjectId('512fbef8a989b28ddb5cdf93')}
    }
  ]
}

在我看来,你可以做到

{
  'actor._id': {'$ne': ObjectId('512fbef8a989b28ddb5cdf93')},
   $or': [
        {'object._id': ObjectId('512fbef8a989b28ddb5cdf93')},
        {'target._id': ObjectId('512fbef8a989b28ddb5cdf93')},
        {'target.user_id': ObjectId('512fbef8a989b28ddb5cdf93')}
      ]
}

另一件事是,使用$ne查询搜索的字段上的索引不是一个好主意。所以我宁愿从该字段中删除索引。