集合c
包含数十万个文档,每个文档都有两个字段(x
和y
)。以下是一些例子。
{ "_id" : ObjectId("53fecab45ae4ec5280a0736f"), "x" : 1, "y" : 1 }
{ "_id" : ObjectId("53fecab45ae4ec5280a07370"), "x" : 2, "y" : 1 }
{ "_id" : ObjectId("53fecab45ae4ec5280a07371"), "x" : 3, "y" : 1 }
{ "_id" : ObjectId("53fecab45ae4ec5280a07372"), "x" : 3, "y" : 2 }
{ "_id" : ObjectId("53fecab45ae4ec5280a07373"), "x" : 3, "y" : 3 }
{ "_id" : ObjectId("53fecab45ae4ec5280a07374"), "x" : 4, "y" : 2 }
{ "_id" : ObjectId("53fecab45ae4ec5280a07376"), "x" : 5, "y" : 1 }
{ "_id" : ObjectId("53fecab45ae4ec5280a07377"), "x" : 5, "y" : 3 }
{ "_id" : ObjectId("53fecab45ae4ec5280a07378"), "x" : 5, "y" : 5 }
{ "_id" : ObjectId("53fecab45ae4ec5280a07379"), "x" : 6, "y" : 2 }
{ "_id" : ObjectId("53fecab45ae4ec5280a0737a"), "x" : 6, "y" : 4 }
{ "_id" : ObjectId("53fecab45ae4ec5280a0737b"), "x" : 6, "y" : 4 }
{ "_id" : ObjectId("53fecab45ae4ec5280a0737c"), "x" : 7, "y" : 3 }
{ "_id" : ObjectId("53fecab45ae4ec5280a0737d"), "x" : 8, "y" : 8 }
{ "_id" : ObjectId("53fecab45ae4ec5280a0737e"), "x" : 9, "y" : 3 }
{ "_id" : ObjectId("53fecab45ae4ec5280a0737f"), "x" : 9, "y" : 1 }
{ "_id" : ObjectId("53fecab45ae4ec5280a07380"), "x" : 10, "y" : 11 }
x
和y
的值是数字类型,但是随机。
现在,我想找到不超过3个文档,其值为least
但larger than or equal to
{x:5,y:3} 。
按功能比较两份文件的规定:
int compareDocument(doc1, doc2) {
var result;
if (doc1.x > doc2.x) {
result = 1;
} else if (doc1.x == doc2.x) {
if (doc1.y > doc2.y) {
result = 1;
} else if (doc1.y == doc2.y) {
result = 0;
} else {
result = -1;
}
} else {
result = -1;
}
return result;
}
必须以高性能执行。我的方法是:
> db.c.ensureIndex({x:1,y:1},{name:"asc"});
> db.c.find().hint("asc").min({x:5,y:3}).limit(3);
{ "_id" : ObjectId("53fecab45ae4ec5280a07377"), "x" : 5, "y" : 3 }
{ "_id" : ObjectId("53fecab45ae4ec5280a07378"), "x" : 5, "y" : 5 }
{ "_id" : ObjectId("53fecab45ae4ec5280a07379"), "x" : 6, "y" : 2 }
> db.c.find().hint("asc").min({x:5,y:3}).limit(3).explain();
{
"cursor" : "BtreeCursor asc",
"isMultiKey" : false,
"n" : 3,
"nscannedObjects" : 3,
"nscanned" : 3,
"nscannedObjectsAllPlans" : 3,
"nscannedAllPlans" : 3,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"start" : {
"x" : 5,
"y" : 3
},
"end" : {
"x" : {
"$maxElement" : 1
},
"y" : {
"$maxElement" : 1
}
}
},
"server" : "Mars-PC:27017"
}
以上仅扫描了3份文件。
同样,我想找到不超过3个文件,其值为largest
,但less than or equal to
{x:5,y:3} 。
是否可以通过使用上述索引asc
或其他内容而不创建新索引来实现此目的,但保持高性能?
我找不到它。我能做的是创建另一个类似的索引来实现它。
> db.c.ensureIndex({x:-1, y:-1},{name:"desc"});
> db.c.find().hint("desc").min({x:5, y:3}).limit(3);
{ "_id" : ObjectId("53fecab45ae4ec5280a07377"), "x" : 5, "y" : 3 }
{ "_id" : ObjectId("53fecab45ae4ec5280a07376"), "x" : 5, "y" : 1 }
{ "_id" : ObjectId("53fecab45ae4ec5280a07374"), "x" : 4, "y" : 2 }
> db.c.find().hint("desc").min({x:5, y:3}).limit(3).explain();
{
"cursor" : "BtreeCursor desc",
"isMultiKey" : false,
"n" : 3,
"nscannedObjects" : 3,
"nscanned" : 3,
"nscannedObjectsAllPlans" : 3,
"nscannedAllPlans" : 3,
"scanAndOrder" : false,
"indexOnly" : false,
"nYields" : 0,
"nChunkSkips" : 0,
"millis" : 0,
"indexBounds" : {
"start" : {
"x" : 5,
"y" : 3
},
"end" : {
"x" : {
"$minElement" : 1
},
"y" : {
"$minElement" : 1
}
}
},
"server" : "Mars-PC:27017"
}