簡體   English   中英

子文檔貓鼬中的更新字段

[英]Update field in sub document mongoose

我的父母模特

var GameChampSchema = new Schema({
  name: String,
  gameId: { type: String, unique: true },
  status: Number,
  countPlayers: {type: Number, default: 0},
  companies: [
    {
      name: String,
      login: String,
      pass: String,
      userId: ObjectId
    }
  ],
  createdAt: {type: Date, default: Date.now},
  updateAt: Date
})

我需要在未設置第一個孩子的情況下插入userId屬性

因此,僅在具有條件({status:0,countPlayers:{$ lt:10})的父對象上需要執行此操作

由於這是一個嵌入式文檔,因此非常容易:

如果要更新作為數組第一個元素的文檔,則該文檔沒有 userId

db.collection.update(
    { 
        "status": 0,
        "countPlayers": {"$lt": 10 },
        "companies.userId": {"$exists": false }
    },
    { "$set": {"companies.$.userId": userId } }
)

這將是很好,但顯然這並沒有匹配的MongoDB如何處理的邏輯,它認為沒有什么,如果有一些 確實有現場數組中存在的匹配。 可以使用聚合框架獲取該元素,但這無助於找到我們需要的位置。

一個簡化的建議是數組中根本沒有元素:

db.collection.update(
    { 
        "status": 0,
        "countPlayers": {"$lt": 10 },
        "companies.0": {"$exists": false }
    },
    { "$push": {"userId": userId } }
)

這只是在陣列上添加了新東西。

我的邏輯是,你確實知道一些關於這個條目,你只是想設置的userId字段。 因此,我將在登錄名上進行匹配

db.collection.update(
    { 
        "status": 0,
        "countPlayers": {"$lt": 10 },
        "companies.login": login,
    },
    { "$set": {"companies.$.userId": userId } }
)

最后,如果這只是更新數組中的第一個元素,那么我們不需要匹配位置,因為我們已經知道它在哪里:

db.collection.update(
    { 
        status: 0, 
        countPlayers: {"$lt": 10 }
    },
    { $set: { "companies.0.userId": userId  } }
)

追溯到我的邏輯案例,請參閱文檔結構:

{ 
    "_id" : ObjectId("530de54e1f41d9f0a260d4cd"),
    "status" : 0,
    "countPlayers" : 5,
    "companies" : [ 
        { "login" : "neil" },
        { "login" : "fred", "userId" : ObjectId("530de6221f41d9f0a260d4ce") },
        { "login": "bill" },
     ] 
}

因此,如果您要查找的是“沒有userId的第一個文檔”,那么這沒有意義,因為有多個項目並且您已經有要更新的特定 userId。 那意味着您必須是其中之一。 我們如何分辨哪一個呢? 在用例中,您似乎正在嘗試根據所擁有的信息將其中的信息與userId進行匹配。

邏輯說,尋找您知道的key value ,並更新匹配的位置

只需用db.collection部分代替您的model對象即可與Mongoose一起使用。

有關相關詳細信息,請參見$ exists以及$ set$ push的文檔。

太謝謝了。

我解決了他的問題

exports.joinGame = function(req, res) {
  winston.info('start method');
  winston.info('header content type: %s', req.headers['content-type']);

  //достаем текущего пользователя
  var currentUser  = service.getCurrentUser(req);
  winston.info('current username %s', currentUser.username);
  //формируем запрос для поиска игры
  var gameQuery = {"status": 0, "close": false};
  gameChamp.findOne(gameQuery, {}, {sort: {"createdAt": 1 }}, function(error, game) {
    if (error) {
      winston.error('error %s', error);
      res.send(error);
    }
    //если игра нашлась
    if (game) {
      winston.info('Append current user to game: %s', game.name);
      //добавляем userId только к одной компании
      var updateFlag = false;
      for (var i=0; i<game.companies.length; i++) {
        if (!game.companies[i].userId && !updateFlag) {
          game.companies[i].userId = currentUser._id;
          updateFlag = true;
          winston.info('Credentials for current user %s', game.companies[i]);
          //если пользовател последний закрываем игру и отправляем в bw, что игра укомплектована
          if (i == (game.companies.length-1)) {
            game.close = true;
            winston.info('game %s closed', game.name);
          }
        }
      }
      //сохраняем игру в MongoDB
      game.save(function(error, game) {
        if (error) {
          winston.error('error %s', error);
          res.send(error);
        }
        if (game) {
          res.send({ game: game })
          winston.info('Append successful to game %s', game.name);
        }
      });
    }
  });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM