在Mongo中,我的文档如下所示:
dateRange: [{
"price": "200",
"dateStart": "2014-01-01",
"dateEnd": "2014-01-30"
},
{
"price": "220",
"dateStart": "2014-02-01",
"dateEnd": "2014-02-15"
}]
好看又简单吧?只是日期和价格。现在,我是一个棘手的派对,我将如何创建一个查询以找到适合2014-01-12的dateRange,然后在找到它之后返回价格而不是整个dateRanges数组?
这些dateRanges可以变得非常大,我正在尝试最小化返回的数据量(如果Mongo可以实现这一点)。注意,我可以根据需要更改日期格式,我只是使用上面的例子。
感谢任何帮助,谢谢!
答案 0 :(得分:1)
您想使用$elemMatch运算符,该运算符仅在版本2.2向上有效。您还需要确保使用multikey indexes。
编辑:要明确,您还必须使用评论$elemMatch find operator中指出的below。
话虽如此,我同意mnemosyn的评论要点。将数组的每个元素表示为单个文档会更好。
$ elemMatch的快速示例,用于演示投影。只需在查找中添加$ elemMatch。
> db.test.save ( {
_id: 1,
zipcode: 63109,
students: [
{ name: "john", school: 102, age: 10 },
{ name: "jess", school: 102, age: 11 },
{ name: "jeff", school: 108, age: 15 }
]
} );
> db.test.find( { zipcode: 63109 }, { students: { $elemMatch: { school: 102 } } } ).pretty() );
{
"_id" : 1,
"students" : [
{
"name" : "john",
"school" : 102,
"age" : 10
}
]
}
答案 1 :(得分:0)
嗯,该模式的问题在于它使用大型嵌入式数组 - 这可能效率很低,因为mongodb查询总是会找到一个文档,而不是嵌入对象的子集。即使您正在使用投影,mongodb也必须在内部读取整个对象,因此如果数组变得很大,比如100k条目,那将会使事情变得迟钝。
为什么不简单地将这些数组元素分成文档,例如
{
price : 200,
productId : ObjectId("foo"), // or whatever the price refers to
dateStart : "2014-01-01",
dateEnd : "2013-01-30"
}
这样,mongodb不需要使用所有价格来拉动整个对象,而只需要与您的日期范围匹配的价格。这将最大限度地减少传输的数据量。然后,您还可以使用query projection仅返回price
,即db.collection.find({ criteria }, {"price" : 1, "_id" : 0})
。
当然,对象的数量会急剧增加,但有效的索引将解决这个问题。引起的唯一低效率是productId
的重复,这比处理大型嵌入式阵列便宜。
P.S:我建议使用实际日期(ISODate
)而不是字符串,即使它们的格式是可排序的。