在meteor / mongodb中创建数组中的新对象(位于文档数组中的对象)

时间:2013-11-14 14:37:37

标签: arrays mongodb nested meteor insert-update

我在mongo-db中创建一个新对象时遇到问题。 我正在使用流星框架,我想添加新的子项目, 到一个子项目阵列。

我的数据结构如下所示:

    { 
       "_id" : "f9d01fd1ef22684353149851", 
       "name" : "Ueberschrift", 
       "items" : [     
                  { "_id" : "be695ec7ffe71152088c57e1",
                    "name" : "asd",
                    "checked" : false,
                    "subitems" : [ ] 
                  },
                  { "_id" : "fe665ec7ffe78852088c22g8",
                    "name" : "asd",
                    "checked" : false,
                    "subitems" : [ ] 
                  } 
                 ] 
     },
     { 
          "_id" : "qw501fd1we522683531qw451",    
          .........
     }, ...

例如,我想添加子项目

 { _id : 1, name : "MySubitemName" }

带有_id的项目:"be695ec7ffe71152088c57e1"
它位于对象"f9d01fd1ef22684353149851"

我使用以下命令执行此操作:

uid => "f9d01fd1ef22684353149851" and
id => "be695ec7ffe71152088c57e1"

Listitems.update({_id:uid, "items._id" : id}, 
  {"items.$.subitems":  {$push: { _id : 1, name : "MySubitemName" }}});

但它不起作用,数据库看起来像以前一样。

有人有想法吗?

2 个答案:

答案 0 :(得分:0)

在定义doc结构时,有一点建议: 避免在自己的架构中使用_id,因为此名称是mongodb的内部代表ObjectId。如果严格要求,请改用id。请参阅http://docs.mongodb.org/manual/reference/object-id/

所以你的文件现在可以像:

{ 
    "id" : "f9d01fd1ef22684353149851", 
     "name" : "Ueberschrift", 
     "items" : [     
            { 
                "id" : "be695ec7ffe71152088c57e1",
                "name" : "iop",
                "checked" : false,
                "subitems" : [ ] 
            },
            { 
                "id" : "fe665ec7ffe78852088c22g8",
                "name" : "asd",
                "checked" : false,
                "subitems" : [ ] 
            } 
         ] 
 }

更新查询:

Listitems.update({ id:"f9d01fd1ef22684353149851", "items.id" : "be695ec7ffe71152088c57e1"},  {$push: {"items.$.subitems" :{ id : 1, name : "MySubitemName" }}});

我已经使用mongodb控制台进行了测试,我假设更新查询中提供的对象与控制台的对象相匹配。

请告诉我们这是否有效。

编辑以改进评论: 由于您在查询时表示实际的对象ID(_id),请查看下面的代码,作为对象引用的可能修复:

uid => ObjectId("f9d01fd1ef22684353149851") and
id => ObjectId("be695ec7ffe71152088c57e1")

Listitems.update({_id:uid, "items._id" : id}, 
  {$push: {"items.$.subitems" :{ id : 1, name : "MySubitemName" }}});

答案 1 :(得分:0)

问题可能是minimongo还不支持mongo的“$”占位符运营商。如果是这种情况,则从服务器调用时更新可能正常运行,但如果从客户端调用则更新失败。你从哪里打电话给那个更新?

有关Meteor团队提供的变通方法的示例,请参阅此处“party”应用的model.js:https://github.com/meteor/meteor/blob/devel/examples/parties/model.js

我已粘贴下面的关键行144-156,包括他们的评论 - 简而言之,他们在服务器上使用“$”并将其替换为客户端上的数组索引。

if (Meteor.isServer) {
    // update the appropriate rsvp entry with $
    Parties.update(
      {_id: partyId, "rsvps.user": this.userId},
      {$set: {"rsvps.$.rsvp": rsvp}});
  } else {
    // minimongo doesn't yet support $ in modifier. as a temporary
    // workaround, make a modifier that uses an index. this is
    // safe on the client since there's only one thread.
    var modifier = {$set: {}};
    modifier.$set["rsvps." + rsvpIndex + ".rsvp"] = rsvp;
    Parties.update(partyId, modifier);
  }