如何使用Mongoose和MongoDB 2.6插入子文档中数组中的特定位置
Posted
技术标签:
【中文标题】如何使用Mongoose和MongoDB 2.6插入子文档中数组中的特定位置【英文标题】:How to insert to the certain position in the array in the subdocument by using Mongoose an MongoDB 2.6 【发布时间】:2014-05-29 18:25:17 【问题描述】:在我的问题的answer 中给出了如何通过使用 Mongoose 来使用 Mongodb 2.6 的新 $position
运算符的一个很好的解释。建议的解决方案非常适合简单的数组。如果数组在子文档中或数组的每个元素都是数组,则建议的解决方案不起作用。我的意思是这样的:
List.collection.update(
/*....*/,
"$push":
"subdocument.list":
"$each": [ 1, 2, 3 ],
"$position": 0
,function(err,NumAffected)
console.log("done");
);
List.collection.update(
/*....*/,
"$push":
"list1.$.list2":
"$each": [ 1, 2, 3 ],
"$position": 0
,function(err,NumAffected)
console.log("done");
);
【问题讨论】:
【参考方案1】:在当前的 Mongoose 版本(4.4.2)中,您可以像这样使用position
:
Foo.update(query.id,
$push:
arrayData:
$each: [
date: new Date
], $position: 0
);
【讨论】:
【参考方案2】:不知道问题出在哪里:
db.list.insert( "list": "sub": [4] )
db.list.update(
,
"$push": "list.sub": "$each": [1,2,3], "$position": 0
)
"list" : "sub" : [ 1, 2, 3, 4 ]
这样就可以按预期工作了。
另外一个例子:
db.list.insert(
outer: [
key: "a",
inner: [4]
,
key: "b",
inner: [4]
]
)
db.list.update(
"outer.key": "b" ,
"$push":
"outer.$.inner":
"$each": [1,2,3], "$position": 0
)
又如预期:
"outer" : [
"key" : "a",
"inner" : [
4
]
,
"key" : "b",
"inner" : [
1,
2,
3,
4
]
]
已经解释了与特定驱动程序的交互,因此数据中肯定有一些不同之处,但如果是这样,那么这些陈述是无效的。
所以使用 Mongoose 也是一样的:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/nodetest');
var listSchema = new Schema(
);
var List = mongoose.model( "List", listSchema );
var Other = mongoose.model( "Other", listSchema );
List.collection.update(
,
"$push":
"list.sub":
"$each": [ 1, 2, 3 ],
"$position": 0
,function(err,NumAffected)
console.log("done");
);
Other.collection.update(
"outer.key": "b" ,
"$push":
"outer.$.inner":
"$each": [ 1, 2, 3 ],
"$position": 0
,function(err,NumAffected)
console.log("done2")
);
【讨论】:
@Roman 您显然没有理解上一个问题的答案。为什么不呢?一旦您绕过驱动程序以外的任何其他交互,那么就没有理由让它起作用。我真的不明白你为什么不能自己尝试。 @Roman 访问.collection
可以让您绕过 mongoose 并使用底层的 Mongo 驱动程序,因此从某种意义上说,它与 Mongoose 一起“工作”,但它也绕过了 Mongoose 的功能。
@Roman 你用的是什么版本的 Mongodb?在 2.6.x 中引入了position
。如果您使用的是 2.4.x,则它不可用。【参考方案3】:
我在 MongooseJS Model.update 中找到了省略对 $position 修饰符的支持的代码。
在 3.8.8 版本中,query.js 的第 1928-1941 行:
if ('$each' in val)
obj[key] =
$each: this._castUpdateVal(schema, val.$each, op)
if (val.$slice)
obj[key].$slice = val.$slice | 0;
if (val.$sort)
obj[key].$sort = val.$sort;
这里,obj[key] 将被设置为 val.$each。您可以看到对设置 $slice 和 $sort 修饰符的明确支持,但 $position 修饰符永远不会被复制到 obj[key] 中。
所以,虽然你可以绕过 MongooseJS 的 Model.update 函数直接访问 MongoDB 的 update 函数,但显然 MongooseJS 的 Model.update 函数不支持 $position 修饰符。
【讨论】:
MongooseJS 3.9 将支持 $position 修饰符:github.com/LearnBoost/mongoose/issues/2024以上是关于如何使用Mongoose和MongoDB 2.6插入子文档中数组中的特定位置的主要内容,如果未能解决你的问题,请参考以下文章
我无法使用 Mongoose 在 MongoDB 中保存或查找文档
如何使用用户名和密码连接 mongodb(mongoose)?
如何在不创建 Mongoose 模型的情况下将 GraphQL 与 Mongoose 和 MongoDB 一起使用