4 回答
TA貢獻1784條經驗 獲得超2個贊
MongoDB 2.2的新$elemMatch投影操作符提供了另一種方法來更改返回的文檔以僅包含第一個匹配的shapes元素:
db.test.find(
{"shapes.color": "red"},
{_id: 0, shapes: {$elemMatch: {color: "red"}}});返回:
{"shapes" : [{"shape": "circle", "color": "red"}]}在2.2中,您也可以使用$ projection operator,其中$投影對象字段名稱表示字段中查詢的第一個匹配數組元素的索引。以下返回與上面相同的結果:
db.test.find({"shapes.color": "red"}, {_id: 0, 'shapes.$': 1});MongoDB 3.2更新
從3.2版本開始,您可以使用新的$filter聚合運算符在投影期間過濾數組,這樣可以包含所有匹配,而不僅僅是第一個匹配。
db.test.aggregate([
// Get just the docs that contain a shapes element where color is 'red'
{$match: {'shapes.color': 'red'}},
{$project: {
shapes: {$filter: {
input: '$shapes',
as: 'shape',
cond: {$eq: ['$$shape.color', 'red']}
}},
_id: 0
}}])結果:
[
{
"shapes" : [
{
"shape" : "circle",
"color" : "red"
}
]
}]TA貢獻1712條經驗 獲得超3個贊
MongoDB 2.2+中的新聚合框架提供了Map / Reduce的替代方案。該$unwind操作可用于分離的shapes陣列到的文件流可以匹配:
db.test.aggregate(
// Start with a $match pipeline which can take advantage of an index and limit documents processed
{ $match : {
"shapes.color": "red"
}},
{ $unwind : "$shapes" },
{ $match : {
"shapes.color": "red"
}})結果是:
{
"result" : [
{
"_id" : ObjectId("504425059b7c9fa7ec92beec"),
"shapes" : {
"shape" : "circle",
"color" : "red"
}
}
],
"ok" : 1}TA貢獻1883條經驗 獲得超3個贊
另一種有趣的方法是使用$ redact,這是MongoDB 2.6的新聚合功能之一。如果您使用的是2.6,則不需要$ unwind,如果您有大型數組,可能會導致性能問題。
db.test.aggregate([
{ $match: {
shapes: { $elemMatch: {color: "red"} }
}},
{ $redact : {
$cond: {
if: { $or : [{ $eq: ["$color","red"] }, { $not : "$color" }]},
then: "$$DESCEND",
else: "$$PRUNE"
}
}}]);$redact “根據文件本身存儲的信息限制文件的內容”。所以它只會在文檔內部運行。它基本上掃描你的文檔頂部到底部,并檢查它是否與你的if條件匹配$cond,如果有匹配,它將保留content($$DESCEND)或remove($$PRUNE)。
在上面的示例中,首先$match返回整個shapes數組,$ redact將其刪除到預期結果。
請注意,這{$not:"$color"}是必要的,因為它也將掃描頂層文檔,如果在頂層$redact找不到color字段,則返回false可能會刪除我們不想要的整個文檔。
- 4 回答
- 0 關注
- 3528 瀏覽
添加回答
舉報
