【问题标题】:How to insert to the certain position in the array in the subdocument by using Mongoose an MongoDB 2.6如何使用Mongoose和MongoDB 2.6插入子文档中数组中的特定位置
【发布时间】:2014-05-29 18:25:17
【问题描述】:

在我的问题的answer 中给出了如何通过使用 Mongoose 来使用 Mongodb 2.6 的新 $position 运算符的一个很好的解释。建议的解决方案非常适合简单的数组。如果数组在子文档中或数组的每个元素都是数组,则建议的解决方案不起作用。我的意思是这样的:

List.collection.update(
{/*....*/},
{ "$push": {
    "subdocument.list": {
      "$each": [ 1, 2, 3 ],
      "$position": 0 }
    }
},function(err,NumAffected) {
  console.log("done");

});
List.collection.update(
{/*....*/},
{ "$push": {
    "list1.$.list2": {
      "$each": [ 1, 2, 3 ],
      "$position": 0 }
    }
},function(err,NumAffected) {
  console.log("done");

});

【问题讨论】:

    标签: mongodb mongoose mongodb-query


    【解决方案1】:

    在当前的 Mongoose 版本(4.4.2)中,您可以像这样使用position

    Foo.update(query.id,
        {
            $push: {
                arrayData: {
                    $each: [{                       
                        date: new Date
                    }], $position: 0 
                }
            }
        });
    

    【讨论】:

      【解决方案2】:

      不知道问题出在哪里:

      db.list.insert({ "list": { "sub": [4] } })
      db.list.update(
          {},
          { "$push": { "list.sub": { "$each": [1,2,3], "$position": 0 } } }
      )
      
      { "list" : { "sub" : [ 1, 2, 3, 4 ] } }
      

      这样就可以按预期工作了。

      另外一个例子:

      db.list.insert({
          outer: [
             {
                 key: "a", 
                 inner: [4]
             },
             {
                 key: "b", 
                 inner: [4]
             }
         ]
      })
      
      db.list.update(
          { "outer.key": "b" },
          { "$push": { 
              "outer.$.inner": { 
                  "$each": [1,2,3], "$position": 0 
              }
          }}
      )
      

      又如预期:

      {
          "outer" : [
                  {
                          "key" : "a",
                          "inner" : [
                                  4
                          ]
                  },
                  {
                          "key" : "b",
                          "inner" : [
                                  1,
                                  2,
                                  3,
                                  4
                          ]
                  }
          ]
      }
      

      已经解释了与特定驱动程序的交互,因此数据中肯定有一些不同之处,但如果是这样,那么这些陈述是无效的。

      所以使用 Mongoose 也是一样的:

      var mongoose = require('mongoose');
      var Schema = mongoose.Schema;
      
      mongoose.connect('mongodb://localhost/nodetest');
      
      var listSchema = new Schema({
      
      });
      
      var List = mongoose.model( "List", listSchema );
      var Other = mongoose.model( "Other", listSchema );
      
        List.collection.update(
          {},
          { "$push": {
          "list.sub": {
            "$each": [ 1, 2, 3 ],
            "$position": 0 }
          }
          },function(err,NumAffected) {
            console.log("done");
      
          }
        );
      
      
        Other.collection.update(
          { "outer.key": "b" },
          { "$push": {
              "outer.$.inner": {
                  "$each": [ 1, 2, 3 ],
                  "$position": 0
              }
          }},function(err,NumAffected) {
            console.log("done2")
          }
        );
      

      【讨论】:

      • @Roman 您显然没有理解上一个问题的答案。为什么不呢?一旦您绕过驱动程序以外的任何其他交互,那么就没有理由让它起作用。我真的不明白你为什么不能自己尝试。
      • @Roman 访问 .collection 可以让您绕过 mongoose 并使用底层的 Mongo 驱动程序,因此从某种意义上说,它与 Mongoose 一起“工作”,但它也绕过了 Mongoose 的功能。
      • @Roman 你用的是什么版本的 Mongodb?在 2.6.x 中引入了position。如果您使用的是 2.4.x,则它不可用。
      【解决方案3】:

      我在 MongooseJS Model.update 中找到了省略对 $position 修饰符的支持的代码。

      在 3.8.8 版本中,query.js 的第 1928-1941 行:

            if ('$each' in val) {
              obj[key] = {
                  $each: this._castUpdateVal(schema, val.$each, op)
              }
      
              if (val.$slice) {
                obj[key].$slice = val.$slice | 0;
              }
      
              if (val.$sort) {
                obj[key].$sort = val.$sort;
              }
      
            }
      

      这里,obj[key] 将被设置为 val.$each。您可以看到对设置 $slice 和 $sort 修饰符的明确支持,但 $position 修饰符永远不会被复制到 obj[key] 中。

      所以,虽然你可以绕过 MongooseJS 的 Model.update 函数直接访问 MongoDB 的 update 函数,但显然 MongooseJS 的 Model.update 函数不支持 $position 修饰符。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-02-01
      • 2018-01-26
      • 1970-01-01
      • 2014-04-30
      • 2019-01-11
      • 2017-09-14
      • 2016-05-02
      相关资源
      最近更新 更多