Javascript 如何动态更新mongodb中的嵌套对象
我们在mongodb中存储了一些任意嵌套的配置Javascript 如何动态更新mongodb中的嵌套对象,javascript,mongodb,mongodb-query,Javascript,Mongodb,Mongodb Query,我们在mongodb中存储了一些任意嵌套的配置 假设我们最初将以下对象存储在mongodb中 现在我想通过添加 const addValue = { 'f': { 'c': 2 } } 类似地,很少有嵌套对象 const addValue1 = { 'a': { 'd': 1 }, 'f': { 'g': 1 } }; 正如我们所添加的,这些键是非常动态的,应该能够更新数据库中的值,但不能替换它,因此期望存储的最终结果应该是 const result = collection.findOne
const addValue = { 'f': { 'c': 2 } }
类似地,很少有嵌套对象
const addValue1 = { 'a': { 'd': 1 }, 'f': { 'g': 1 } };
正如我们所添加的,这些键是非常动态的,应该能够更新数据库中的值,但不能替换它,因此期望存储的最终结果应该是
const result = collection.findOne({ userId });
console.log(result);
{ 'a': { 'b': 1, 'd': 1 }, 'f': { 'g': 1, 'c': 2 } }
如果udpate值为
const addValue2 = { 'a': { 'b' : { 'e': 1 } } }
预期结果是
const result2 = { 'a': { 'b': { 'e': 1 } , 'd': 1 }, 'f': { 'g': 1, 'c': 2 } }
删除时也是如此
删除所使用的方法
public async removeValue(key: string) {
return await this.remove(JSON.parse(`{\"${key}\": "" }`));
}
private remove(value) {
return new Promise((resolve, reject) => {
this.collection.updateOne({ user: this.userId }, {
$unset: value,
}, { upsert: false }, function (err, res) {
if (err) {
reject(err);
} else {
console.log('REUSLL AFTER REMOVE', res.);
resolve({ id: true });
}
});
});
}
这里的困难在于必须将对象转换为MongoDB的点表示法,该点表示法可用于构建update语句。您可以通过运行以下函数来完成此操作:
let flatten=(对象、前缀、结果)=>{
结果=结果|{};
for(对象的let键。键(obj)){
让keyExpr=prefix?`${prefix}.${key}`:`${key}`;
if(对象类型[键]=“对象”){
展平(obj[key],keyExpr,result);
}否则{
结果[keyExpr]=obj[key];
}
}
返回结果;
}
常量addValue={f':{c':2}
让update1=展平(addValue)
console.log(update1);
常量addValue1={'a':{'d':1},'f':{'g':1};
让update2=展平(addValue1);
console.log(update2)代码>这里的困难在于必须将对象转换为MongoDB的点表示法,该点表示法可用于构建update语句。您可以通过运行以下函数来完成此操作:
let flatten=(对象、前缀、结果)=>{
结果=结果|{};
for(对象的let键。键(obj)){
让keyExpr=prefix?`${prefix}.${key}`:`${key}`;
if(对象类型[键]=“对象”){
展平(obj[key],keyExpr,result);
}否则{
结果[keyExpr]=obj[key];
}
}
返回结果;
}
常量addValue={f':{c':2}
让update1=展平(addValue)
console.log(update1);
常量addValue1={'a':{'d':1},'f':{'g':1};
让update2=展平(addValue1);
console.log(update2)代码>有意义让我快速测试it@user1595858测试进行得怎么样:)?很好地添加了值。但是在删除方面有问题。@user1595858最初没有提到有任何删除。稍后我可以看一下:-)@user1595858关于您的删除示例:每当您运行updateOne
时,您都不知道a
字段的状态。您只需取消设置您知道的是a.b
的密钥,但不知道是否有a.c
、a.d
等。您所能做的就是运行$unset
并稍后以某种方式处理空对象。或者,您需要先查找文档,然后运行更新,知道它的全部内容-但这是两次数据库往返,所以您可以决定哪种方式更可取。有意义让我快速测试一下it@user1595858测试进行得怎么样:)?很好地添加了值。但是在删除方面有问题。@user1595858最初没有提到有任何删除。稍后我可以看一下:-)@user1595858关于您的删除示例:每当您运行updateOne
时,您都不知道a
字段的状态。您只需取消设置您知道的是a.b
的密钥,但不知道是否有a.c
、a.d
等。您所能做的就是运行$unset
并稍后以某种方式处理空对象。或者,您需要先查找文档,然后运行update,知道它的全部内容-但这是两次数据库往返,因此您可以决定采用哪种方式。
let testObject = new MongoDBStorageService('test', dbConnection as any, 'userTestSchema');
testObject.load({ 'a': { 'b': 1 }});
testObject.removeValue('a.b');
const content = await testObject.contents;
expect(content).toEqual({}); // but we see output as `{ a: {} }`
public async removeValue(key: string) {
return await this.remove(JSON.parse(`{\"${key}\": "" }`));
}
private remove(value) {
return new Promise((resolve, reject) => {
this.collection.updateOne({ user: this.userId }, {
$unset: value,
}, { upsert: false }, function (err, res) {
if (err) {
reject(err);
} else {
console.log('REUSLL AFTER REMOVE', res.);
resolve({ id: true });
}
});
});
}