Node.js mongo能否插入阵列数据?
我有一个像这样的mongo文档Node.js mongo能否插入阵列数据?,node.js,mongodb,Node.js,Mongodb,我有一个像这样的mongo文档 { "_id" : ObjectId("50b429ba0e27b508d854483e"), "array" : [ { "id" : "1", "letter" : "a" }, { "id" : "2", "letter" : "b" } ], "tester" : "
{
"_id" : ObjectId("50b429ba0e27b508d854483e"),
"array" : [
{
"id" : "1",
"letter" : "a"
},
{
"id" : "2",
"letter" : "b"
}
],
"tester" : "tom"
}
我希望能够使用单个mongo命令插入和更新数组
,并且不在find()
中使用条件,然后根据对象的存在运行insert()
和update()
id
是我想要作为选择器的项。因此,如果我使用以下内容更新阵列:
{
"id" : "2",
"letter" : "c"
}
我必须使用$set
语句
db.soup.update({
"tester":"tom",
'array.id': '2'
}, {
$set: {
'array.$.letter': 'c'
}
})
db.soup.update({
"tester":"tom"
}, {
$push: {
'array': {
"id": "3",
"letter": "d"
}
}
})
如果我想在数组中插入一个新对象
{
"id" : "3",
"letter" : "d"
}
我必须使用$push
语句
db.soup.update({
"tester":"tom",
'array.id': '2'
}, {
$set: {
'array.$.letter': 'c'
}
})
db.soup.update({
"tester":"tom"
}, {
$push: {
'array': {
"id": "3",
"letter": "d"
}
}
})
我需要一种数组项的upsert
我是否必须以编程方式执行此操作,还是可以通过单个mongo调用执行此操作?我不知道有哪个选项会像MongoDB 2.2那样插入嵌入式阵列,因此您可能必须在应用程序代码中处理此问题
假定要将嵌入数组视为虚拟集合的类型,则可能需要考虑将数组建模为单独的集合。 您不能基于嵌入数组中的字段值执行upsert,但如果嵌入文档不存在,您可以使用它来插入该文档:
db.soup.update({
"tester":"tom"
}, {
$addToSet: {
'array': {
"id": "3",
"letter": "d"
}
}
})
这不适合通过数组元素的
id
进行匹配的确切用例,但如果您知道预期的当前值,则可能会很有用。我自己也遇到了这个问题。我找不到一次调用的解决方案,但我找到了一个两次调用的解决方案,当数组元素中有一个唯一的值时,它就可以工作。首先使用$pull
命令从数组中删除元素,然后使用$push
db.soup.update({
"tester":"tom"
}, {
$pull: {
'array': {
"id": "3"
}
}
})
db.soup.update({
"tester":"tom"
}, {
$push: {
'array': {
"id": "3",
"letter": "d"
}
}
})
当文档不存在时,当文档存在但数组中的条目不存在时,以及当条目存在时,这应该可以工作
同样,这只适用于在数组元素之间具有唯一性的内容(如本例中的
id
字段)的情况。如果可以将文档重新构造为使用对象而不是数组,则在某些情况下可以实现嵌入文档集的升级。我刚刚回答了这个问题,但为了方便起见,我将在这里对其进行调整
一个例子是
{
tester: 'tom',
items: {
'1': 'a',
'2': 'b'
}
}
要向上插入id为3且值为“c”的项,需要执行以下操作
db.coll.update(
{ tester: 'tom' },
{ $set: { 'items.3': 'c' } }
)
一个缺点是查询字段名(使用$exists
查询运算符)需要扫描。您可以通过添加一个额外的存储属性名的数组字段来解决这个问题。此字段可以正常索引和查询。上升的部分变成
db.coll.update(
{ tester: 'tom' },
{
$set: { 'items.3': 'c' },
$addToSet: { itemNames: 3 }
}
)
(请记住,$addToSet
是O(n)。)删除属性时,还必须将其从数组中拉出
db.widgets.update(
{ tester: 'tom' },
{
$unset: { 'items.3': true },
$pull: { itemNames: 3 }
}
)
嘿,你可以使用数组过滤器选项。
你可以在这里查阅
问题来自2012年。我查看了mongo文档:Rob Watts在评论中提到了该文档,但它非常稀少
我在这里找到了答案:请注意,对嵌入式文档提供某种形式的“虚拟收藏”支持是一种流行的要求。。您可以在MongoDB问题跟踪器中投票/观看。谢谢,在DocumentAddA$exists
签入$push
查询中使用两个字段进行搜索时,它工作得很好。因此,如果两次调用之间出现问题,它将失败。几年后,我也在寻找解决此问题的方法。有更新吗?@DauleDK快速搜索发现:你认为批量查找upsert可以在一次查询中解决此问题吗?这是可行的,但请注意,你将失去按ID索引项目的能力,因为mongo没有办法在给定子对象的所有键上创建索引。mongo仍然没有我在使用mongo的每个项目中多次遇到的基本功能,这让我感到惊讶:/这将非常有用,但在我看来,它只有在更新对象和数组过滤器中的标识符相同时才起作用,例如:db.collection.update({'tester':'tom'},{$set:{“array.$[element].letter:“c”},{arrayFilters:[{“element.letter:”b“})
-这没有多大帮助。此外,文档中提到的upsert
选项允许您在不匹配的情况下插入新文档,并且不向数组中添加新元素,因此这并不能解决OPs问题。