我有访客的集合。每个访问者都包含品牌ID和trans数组,其中包含{ct:Date,total:Number}等文档。我尝试让两个日期之间有交易的访问者...我也有{brandid:1,trans.ct:1}的索引以下是我的疑问:
/*1*/
db.visitors.find({
brandid:12,
'trans':{
$elemMatch:{
ct:{
$gte:ISODate("2015-01-17"),
$lt:ISODate("2015-01-18")
}
}
}
})
.hint("transct")
/*2*/
db.visitors.find({
brandid:12,
'trans.ct':{
$elemMatch:{
$gte:ISODate("2015-01-17"),
$lt:ISODate("2015-01-18")
}
}
})
.hint("transct")
第一个查询返回42个文档,第二个查询返回0
以上是对上述查询的解释
/* 1 */
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "m.visitors",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"trans" : {
"$elemMatch" : {
"$and" : [
{
"ct" : {
"$lt" : ISODate("2015-01-18T00:00:00.000Z")
}
},
{
"ct" : {
"$gte" : ISODate("2015-01-17T00:00:00.000Z")
}
}
]
}
}
},
{
"brandid" : {
"$eq" : 12
}
}
]
},
"winningPlan" : {
"stage" : "KEEP_MUTATIONS",
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"trans" : {
"$elemMatch" : {
"$and" : [
{
"ct" : {
"$lt" : ISODate("2015-01-18T00:00:00.000Z")
}
},
{
"ct" : {
"$gte" : ISODate("2015-01-17T00:00:00.000Z")
}
}
]
}
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"brandid" : 1,
"trans.ct" : 1
},
"indexName" : "transct",
"isMultiKey" : true,
"direction" : "forward",
"indexBounds" : {
"brandid" : [
"[12.0, 12.0]"
],
"trans.ct" : [
"(true, new Date(1421539200000))"
]
}
}
}
},
"rejectedPlans" : []
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 42,
"executionTimeMillis" : 99,
"totalKeysExamined" : 78999,
"totalDocsExamined" : 38063,
"executionStages" : {
"stage" : "KEEP_MUTATIONS",
"nReturned" : 42,
"executionTimeMillisEstimate" : 100,
"works" : 79000,
"advanced" : 42,
"needTime" : 78957,
"needFetch" : 0,
"saveState" : 617,
"restoreState" : 617,
"isEOF" : 1,
"invalidates" : 0,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"trans" : {
"$elemMatch" : {
"$and" : [
{
"ct" : {
"$lt" : ISODate("2015-01-18T00:00:00.000Z")
}
},
{
"ct" : {
"$gte" : ISODate("2015-01-17T00:00:00.000Z")
}
}
]
}
}
},
"nReturned" : 42,
"executionTimeMillisEstimate" : 100,
"works" : 79000,
"advanced" : 42,
"needTime" : 78957,
"needFetch" : 0,
"saveState" : 617,
"restoreState" : 617,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 38063,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 38063,
"executionTimeMillisEstimate" : 60,
"works" : 79000,
"advanced" : 38063,
"needTime" : 40936,
"needFetch" : 0,
"saveState" : 617,
"restoreState" : 617,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"brandid" : 1,
"trans.ct" : 1
},
"indexName" : "transct",
"isMultiKey" : true,
"direction" : "forward",
"indexBounds" : {
"brandid" : [
"[12.0, 12.0]"
],
"trans.ct" : [
"(true, new Date(1421539200000))"
]
},
"keysExamined" : 78999,
"dupsTested" : 78999,
"dupsDropped" : 40936,
"seenInvalidated" : 0,
"matchTested" : 0
}
}
},
"allPlansExecution" : []
},
"serverInfo" : {
"host" : "linux-jxch",
"port" : 27017,
"version" : "3.0.0",
"gitVersion" : "a841fd6394365954886924a35076691b4d149168"
}
}
/* 2 */
{
"queryPlanner" : {
"plannerVersion" : 1,
"namespace" : "m.visitors",
"indexFilterSet" : false,
"parsedQuery" : {
"$and" : [
{
"trans.ct" : {
"$elemMatch" : {
"" : {
"$lt" : ISODate("2015-01-18T00:00:00.000Z")
},
"" : {
"$gte" : ISODate("2015-01-17T00:00:00.000Z")
}
}
}
},
{
"brandid" : {
"$eq" : 12
}
}
]
},
"winningPlan" : {
"stage" : "KEEP_MUTATIONS",
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"trans.ct" : {
"$elemMatch" : {
"" : {
"$lt" : ISODate("2015-01-18T00:00:00.000Z")
},
"" : {
"$gte" : ISODate("2015-01-17T00:00:00.000Z")
}
}
}
},
"inputStage" : {
"stage" : "IXSCAN",
"keyPattern" : {
"brandid" : 1,
"trans.ct" : 1
},
"indexName" : "transct",
"isMultiKey" : true,
"direction" : "forward",
"indexBounds" : {
"brandid" : [
"[12.0, 12.0]"
],
"trans.ct" : [
"[new Date(1421452800000), new Date(1421539200000))"
]
}
}
}
},
"rejectedPlans" : []
},
"executionStats" : {
"executionSuccess" : true,
"nReturned" : 0,
"executionTimeMillis" : 0,
"totalKeysExamined" : 42,
"totalDocsExamined" : 42,
"executionStages" : {
"stage" : "KEEP_MUTATIONS",
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 43,
"advanced" : 0,
"needTime" : 42,
"needFetch" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"inputStage" : {
"stage" : "FETCH",
"filter" : {
"trans.ct" : {
"$elemMatch" : {
"" : {
"$lt" : ISODate("2015-01-18T00:00:00.000Z")
},
"" : {
"$gte" : ISODate("2015-01-17T00:00:00.000Z")
}
}
}
},
"nReturned" : 0,
"executionTimeMillisEstimate" : 0,
"works" : 43,
"advanced" : 0,
"needTime" : 42,
"needFetch" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"docsExamined" : 42,
"alreadyHasObj" : 0,
"inputStage" : {
"stage" : "IXSCAN",
"nReturned" : 42,
"executionTimeMillisEstimate" : 0,
"works" : 43,
"advanced" : 42,
"needTime" : 0,
"needFetch" : 0,
"saveState" : 0,
"restoreState" : 0,
"isEOF" : 1,
"invalidates" : 0,
"keyPattern" : {
"brandid" : 1,
"trans.ct" : 1
},
"indexName" : "transct",
"isMultiKey" : true,
"direction" : "forward",
"indexBounds" : {
"brandid" : [
"[12.0, 12.0]"
],
"trans.ct" : [
"[new Date(1421452800000), new Date(1421539200000))"
]
},
"keysExamined" : 42,
"dupsTested" : 42,
"dupsDropped" : 0,
"seenInvalidated" : 0,
"matchTested" : 0
}
}
},
"allPlansExecution" : []
},
"serverInfo" : {
"host" : "linux-jxch",
"port" : 27017,
"version" : "3.0.0",
"gitVersion" : "a841fd6394365954886924a35076691b4d149168"
}
}
如何强制第一个查询使用索引,或者如何强制第二个查询返回正确的数据?
以下是第一个查询返回的数据示例:
/* 40 */
{
"_id" : ObjectId("54cbfbe06f352a17778b483d"),
"brandid" : NumberLong(12),
"trans" : [
{
"id" : "54cbfbcd6f352a09778b481e",
"ct" : ISODate("2015-01-17T18:55:29.000Z"),
"t" : 891.09
}
]
}
/* 41 */
{
"_id" : ObjectId("54cbfbe16f352a17778b4b8b"),
"brandid" : NumberLong(12),
"trans" : [
{
"id" : "54cbfbcd6f352a09778b481f",
"ct" : ISODate("2015-01-17T18:59:24.000Z"),
"t" : 689.45
}
]
}
第二个查询不会返回任何文件。
此外" transct"索引看起来像:
{
"brandid" : 1,
"trans.ct" : 1
}
访客收藏有超过900K的文件。他们中的大多数看起来与上面的例子相同,但有不同的品牌ID,当然" ct"反转数组中的日期。