我有一个包含文档的集合,这些文档的数组字段如下:
_id: 123
my_array_field: [ 5, 7, 4]
现在,我想通过单个操作“切换”该数组中某个元素的存在。例如,如果我发送值3,则应将其添加到数组中,因为它尚不在其中。如果我发送值5,则应将其删除。无需事先查询文档就可以做到吗?
我正在使用当前版本的MongoDB(4.0.8)和当前的NodeJS驱动程序(3.2.3)。
谢谢!
答案 0 :(得分:0)
在Aggregate框架内,文档是在流水线开始时预先获取的,然后经过所有阶段进行处理。
“ testDb”中的“ testCollection”具有以下文档:
/* 1 */
{
"_id" : ObjectId("5cb72e0010d85108dd5f05d5"),
"my_array_field" : [
5,
7,
4
]
}
/* 2 */
{
"_id" : ObjectId("5cbae5f62df7de6e1f5f6d21"),
"my_array_field" : [
1,
2,
3
]
}
以下是使用mongodb nodejs驱动程序v3.2.3的工作代码:
const mongodb = require('mongodb');
const MongoClient = mongodb.MongoClient;
// Connection URL
const url = 'mongodb://localhost:27017';
// Database Name
const dbName = 'testDb';
MongoClient.connect(url, function(err, client) {
console.log("Connected successfully to server");
let val = [8]; //value to add into the my_array_field. And if it is already present then all its occurences are removed
const db = client.db(dbName);
const collection = db.collection('testCollection');
collection.aggregate([
{
$match: {_id : mongodb.ObjectID('5cb72e0010d85108dd5f05d5')}
},
{
$project: {
my_array_field: {
$concatArrays: ['$my_array_field', val]
}
}
},
{
$unwind: "$my_array_field"
},
{
$group: {
_id: {
id: "$_id",
val: "$my_array_field"
},
count: {$sum: 1}
}
},
{
$match: {
"_id.val" : {
$ne : null
},
count : {
$lt: 2
}
}
},
{
$group: {
_id: "$_id.id",
my_array_field: {$push: "$_id.val"}
}
}
]).toArray(function(err, docs) {
console.log(docs);
console.log(err);
//updated the aggregate pipeline result back to the collection
collection.findOneAndUpdate(
{_id: docs[0]._id},
{$set: {my_array_field: docs[0].my_array_field}}).then(function(docs) {
console.log("document updated!")
client.close();
})
});
如果将8添加到文档[5,7,4],则生成以下输出:
{
"_id" : ObjectId("5cb72e0010d85108dd5f05d5"),
"my_array_field" : [
8,
4,
7,
5
]
}
如果将7添加到文档[5,7,4],则生成以下输出:
{
"_id" : ObjectId("5cb72e0010d85108dd5f05d5"),
"my_array_field" : [
4,
5
]
}