我在执行推送到嵌套数组时遇到问题,我试图在嵌套数组“fieldList”中添加一个或多个对象,当我执行推送时它告诉我可以,但当我检查它时它尚未更新它。
{
_id: ObjectId('6628363d6ed5718acbd2af72'),
label: 'Movimiento Vehicular IDAAN',
folders: [
{
name: 'Datos Generales',
fieldList: [],
_id: ObjectId('6628367b6ed5718acbd2af9f')
},
{
name: 'Datos de Vehículo y Conductor',
fieldList: [],
_id: ObjectId('6628555de630217d0abafcc5')
}
],
createdAt: ISODate('2024-04-23T22:29:17.213Z'),
updatedAt: ISODate('2024-04-24T00:42:05.879Z')
}
我试图用
$push
添加它,点符号 { $push: { "folders.fieldList": newfield}}
告诉我它执行正常,但没有添加。这是我正在使用的代码:
要添加的对象:
{
"name": "Dia",
"label": "Dia",
"order": 11,
"type": "number",
"requ": true,
"par": "Datos Generales"
}
Update Script:
export const newfieldwithfolder = async (req: Request, res: Response) => {
try {
const { name, label, order, type, requ, par } = req.body;
const query = { _id: req.params.id };
const updateQuery = new Fields({
name,
label,
order,
type,
requ,
par,
});
const newfield = { $push: { "folders.fieldList": updateQuery } };
const result = await Template.updateOne(query, newfield);
console.log(result);
res.status(201).json({ message: "Fields have been added successfully!" });
} catch (error) {
console.error(error);
res.status(500).json({ success: false, error: "Something went Wrong!" });
}
};
@prasad_ 已经回答了。这篇文章的目的是为同一答案添加一些上下文。
简短回答:
这个原始问题所属的子文档数组和子文档嵌套数组使用过滤位置运算符$[]进行更新。首先要查询各个数组,找到其索引并在更新时使用。过滤位置操作与 arrayFilters 一起完成这项工作。下面所附的“操作日志”部分将包含这方面的示例声明。请求在随附的评论的帮助下按顺序阅读该部分。
详细解答:
这是访问或更新嵌套文档结构的情况。
众所周知,嵌套结构主要有两种类型:
为了阅读时的简洁性和一致性,“子文档”和“子文档数组”是以下部分中使用的两个术语。
子文档处理起来相对简单,因为它基本上是一种分组机制。值得注意的是,子文档中的所有键仍然可以通过顶级文档的 _id 来识别,并且可以通过点表示法进行访问。
带有一个子文档的示例文档
test> { _id : 1, a : { a : 1 } }
上面的子文档 { a : 1} 可以通过顶级文档 _id 来识别,并且它的键“a”可以通过点符号访问,如下所示:
test> db.collection.updateOne({_id : 1}, { $set : { "a.a" : 2 } } )
test> db.a.find();
[ { _id: 1, a: { a: 2 } } ]
但是,子文档数组不仅仅是一个简单的子文档。
虽然像子文档一样,子文档数组仍然可以通过顶级 _id 进行识别,并且可以通过点表示法进行访问,但“数组性质”仍然将其与子文档的简单性区分开来。它的“数组性质”需要另一个维度——“位置”或“索引”,也需要注意。基本点是在访问之前需要搜索各个数组并找到数组索引。这就是它与访问简单的子文档的不同之处。子文档嵌套数组的情况也涉及相同的步骤。在这样的背景下,下面的行动日志可能更有意义。
操作日志:
// Using MongoDB: 7.0.2
// Using Mongosh: 2.1.1
test> use test // using test db
test> t = db.test // just for convenience
test> t.drop() // optional statement
// “a” is a key of an Array of sub documents
// “a.a” is a key of Nested Array of sub documents
// the following statement creates a document,
// note that the value of the array key “a.a” now is an empty array.
test> t.insertOne({ _id:'1', a: [ { _id:'1.1', a : [ ] } ] } );
test> t.find();
[
{ _id: '1', a: [ { _id: '1.1', a: [] } ] }
]
// the following statement inserts a new object into the array key “a.a”
// the filtered array expression “a.$[i]” acts a placeholder for
// the matched elements in the arrayFilter expression - {arrayFilters:[{"i._id":'1.1'}]}
// Therefore it essentially finds the matching object in the array key “a” and
// then pushes a new object { a: ‘1.1.1’ } into the key “a” within the matched object.
// Please see the output as well.
test> t.updateOne({_id:'1'}, { $push: {"a.$[i].a":{a:'1.1.1'}}}, {arrayFilters:[{"i._id":'1.1'}]});
test> t.find();
[
{
_id: '1',
a: [
{ _id: '1.1', a: [ { a: '1.1.1' } ] }
]
}
]
// the following statement differs from the previous statement not only from action but also
// from the array (nested array) it tries to access. This query tries to update
// the nested array field “a.a”.
// therefore the arrayFilter expression - {arrayFilters:[{"i._id":'1.1'},{"j.a":'1.1.1'}]}),
// has one more conditional - {"j.a":'1.1.1'}]}.
// Please recall that the key “a.a” unlike the key “a” is a Nested array of sub documents.
// Therefore both query conditionals are to be matched to locate the target object.
test> t.updateOne({_id:'1'}, { $set: {"a.$[i].a.$[j].a":'1.1.2'}}, {arrayFilters:[{"i._id":'1.1'},{"j.a":'1.1.1'}]});
test> t.find();
[
{
_id: '1',
a: [
{ _id: '1.1', a: [ { a: '1.1.2' } ] }
]
}
]