【问题标题】:Mongo DB insert into a sub document if sub document value doesn't exist如果子文档值不存在,Mongodb 插入子文档
【发布时间】:2016-03-01 06:45:48
【问题描述】:

我对 mongodb 很陌生,有点迷茫。

我有一个看起来像这样的 mongo db 集合:

  ({
    _id:id ,
    createdAt: new Date(),
    name:name,
    friends : [{name:1,children:[{name:sarah,age:12}]}],
    dogs : [{}]
  });

如果名称不存在,我希望能够在朋友数组中插入一个新元素,并在该新数组中插入一个子元素。

伪代码是

If Directory.find id.friends.name = true

update and add a new children document {name:"sarah",age:5}

else

make a new friend element with a new children subdocument

经过大量研究,似乎人们建议使用 $exist,但我找不到在子文档中使用它的方法'

我想出了这个,但它并没有真正起作用,我想知道如何将它用于我的 if else 语句:

db.Directory.find({_id:id},{friends.name:"foo", {"$exists": True}})

用于实际查询

db.Directory.update(
    { _id: id, 'friends.name': "foo" },
    {$push: {'friends.$.children':  {name:"x",age:"yy"}}}
)

如果它不存在:

db.Directory.insert(
    { _id: id, 'friends.name': "foo" },
    {$push: {'friends.$.children':  {name:"x",age:"yy"}}}
)

但这并没有真正起作用,我不确定我的公式是否有问题,因为这是研究中的大量试验和错误。 我也不知道这是否是正确的方法,因为我在子文档上的值上找不到任何东西,并计划尝试进行 Find() 搜索存储该值,然后测试是否为真或JS 中的结果为 false 以进行更新/插入调用。

希望有人能帮忙

编辑: 假设我想将 {name:john,age:15} 添加到该朋友 name:1

friends : [{name:1,children:[{name:sarah,age:12}]}]

我希望输出是

friends : [{name:1,children:[{name:sarah,age:12},{name:john,age:15}]}]

或者如果名字 1 不存在

friends : []

让它输出

friends : [{name:1,children:[{name:john,age:15}]}]

更新示例:

案例一:

friends : []

我添加了一个新朋友,名字叫“josh”,有一个孩子 sarah,我得到了 12 岁:

friends : [{name:"josh",children:[{name:sarah,age:12}]}]

这是完美的。

Now i add a new friend name 2 with children tom 15.

什么都没有发生。

之后,我想给 josh 添加一个新的孩子,15 岁的 timmy

我明白了:

friends : [{name:"josh",children:[{name:timmy,age:12}]}]

莎拉消失了。

【问题讨论】:

    标签: javascript mongodb meteor mongodb-query


    【解决方案1】:

    请尝试通过Bulk operation 操作,通过$addToSet 操作符添加一位新朋友,通过$set 操作符更新朋友,等你的问题更清楚后再更新。

    var bulk = db.Directory.initializeOrderedBulkOp();
    
    // if `friends` is `[]`, push the empty children firstly through addToSet
    bulk.find({_id: id, 'friends.name': {$exists: false}}).updateOne(
         {$addToSet: {friends: {name: 1, children: []}});
    
    // if we find the match friend, update this one through `$set`
    bulk.find({_id: id, 'friends.children.name': 'john'}).updateOne(
        {$set: {'friends.$.children': {name: 'john', age: 22}}});
    
    // if we cannot find match friend, insert the new one through `$addToSet`
    bulk.find({_id: id, 'friends.children.name': {$ne: "john"}}).updateOne( 
        {$addToSet: {'friends.0.children': {name: 'john', age: 12}}});
    
    bulk.execute();
    

    【讨论】:

    • 感谢您的帮助。那么,“nameinput”可以是 js(string) 变量,对吧?另外,第一个表达式是否将新元素{name:x,age:yy} 推送到friends.name=name 子元素输入数组(用户可以有多个子元素)?
    • @user697,是的,“名称输入”可以是 js(字符串)变量。 $set 刚刚更新的老朋友名字是'nameinput'。而addToSet 会将新朋友添加到friends 数组中,只有插入的值不存在于friends 数组中。
    • 嘿,经过很多困难,我已经成功地在流星上实现了批量,但似乎我找不到 mongo 公式的问题,因为它实际上是在添加一个新的“朋友”数组在我的主要元素结束时,而不是更新孩子们.. oyu 知道为什么吗? (我已经更新了帖子,以防我不清楚)
    • @user697,你的意思是{$addToSet: {'friends.0.children': {name: 'john', age: 12}}}不起作用?你能给我一些例子吗?因为我测试它在我的测试数据中运行良好。
    • @user697,哇,你让我很困惑,你现在描述的与你在问题中所说的不同......太伤心了......或者你没有在你的问题中提供所有信息.
    猜你喜欢
    • 2014-06-21
    • 2016-04-14
    • 2023-04-05
    • 2013-11-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-13
    相关资源
    最近更新 更多