来自探查器的查询的.explain()`

时间:2017-04-06 12:27:58

标签: mongodb mongodb-query

TL; DR:是否有一种本地方式可以通过传递整个探查器结果或只是查询部分来对探查器的查询运行.explain()?

查询

db.test.find({ "name": "Ale" })

运行此查询后,我们可以检索system.profile,如下所示:

{
    "op" : "query",
    "ns" : "test.test",
    "query" : {
        "find" : "test",
        "filter" : {
            "name" : "Ale"
        }
    },
    "keysExamined" : 0,
    "docsExamined" : 27,
    "cursorExhausted" : true,
    "numYield" : 0,
    "locks" : {
        "Global" : {
            "acquireCount" : {
                "r" : NumberLong(2)
            }
        },
        "Database" : {
            "acquireCount" : {
                "r" : NumberLong(1)
            }
        },
        "Collection" : {
            "acquireCount" : {
                "r" : NumberLong(1)
            }
        }
    },
    "nreturned" : 1,
    "responseLength" : 149,
    "protocol" : "op_command",
    "millis" : 12,
    "planSummary" : "COLLSCAN",
    "execStats" : {
        "stage" : "COLLSCAN",
        "filter" : {
            "name" : {
                "$eq" : "Ale"
            }
        },
        "nReturned" : 1,
        "executionTimeMillisEstimate" : 0,
        "works" : 29,
        "advanced" : 1,
        "needTime" : 27,
        "needYield" : 0,
        "saveState" : 0,
        "restoreState" : 0,
        "isEOF" : 1,
        "invalidates" : 0,
        "direction" : "forward",
        "docsExamined" : 27
    },
    "ts" : ISODate("2017-03-28T12:00:29.582Z"),
    "client" : "127.0.0.1",
    "appName" : "MongoDB Shell",
    "allUsers" : [ ],
    "user" : ""
}

现在,我想对来自探查器的查询运行.explain()。我无法访问原始查询,只能访问探查器,因此查看探测器中的查询,如下所示(从上面的探查器输出中提取后):

"op" : "query",
"ns" : "test.test",
"query" : {
    "find" : "test",
    "filter" : {
        "name" : "Ale"
    }
}

为了能够对此查询运行.explain(),我需要将其转换回格式:

db.test.find({ "name": "Ale" })

并将.explain()附加到其中:

db.test.find({ "name": "Ale" }).explain()

这有点问题,因为您可以使用不同的查询类型 - 不仅find()而且aggregate()count()distinct()group(),{ {1}}和remove()

通过传递整个探查器结果或仅传递查询部分,是否有可能通过本地方式在探查器上运行.explain()

1 个答案:

答案 0 :(得分:1)

db.runCommand({ "find" : "test", "filter" : { "name" : "Ale" } }) 值为db.runCommand()格式,因此您可以将其重复为:

var query = db.system.profile.findOne({...}).query;
db.runCommand(query);

db.runCommand({
    explain: {
        "find" : "test",
        "filter" : {
            "name" : "Ale"
        }
    }
})

要解释此查询,您可以在explain命令中使用它:

var query = db.system.profile.findOne({...}).query;
db.runCommand({explain: query});

update

修改

var update = (({ ns, query, updateobj }) => ({ update: ns.split(/\./).slice(1).join('.'), // collection name updates:[{q:query, u:updateobj}] // filter and update }))(db.system.profile.findOne({"op" : "update", ... })); db.runCommand({explain: update}); 命令的示例需要进行一些重新整形:

# .---------------- minute (0 - 59)
# |  .------------- hour (0 - 23)
# |  |  .---------- day of month (1 - 31)
# |  |  |  .------- month (1 - 12) OR jan,feb,mar,apr ...
# |  |  |  |  .---- day of week (0 - 6) (Sunday=0 or 7) OR sun,mon,tue,wed,thu,fri,sat
# |  |  |  |  |
# *  *  *  *  * user-name  command to be executed

# test entry
* * * * * echo `who am i` > /home/2125/RR_Dev_Code/ETL/crontab.test