簡體   English   中英

如何使用Mongoose查找子文檔?

[英]How to find a sub-document using Mongoose?

我正在嘗試使用貓鼬在User集合中獲取子文檔。 我在其官方網站上關注了貓鼬子文檔 上面寫着:

每個文檔都有一個_id。 DocumentArrays具有一種特殊的id方法,用於通過其_id查找文檔。

var doc = parent.children.id(id);

這是我的代碼:

exports.editAccount = function(req, res) {
    var user = new User(req.user);
    var newAccount = new Account(req.body);
    console.log("Account:" + newAccount._id); // Gave me 53bf93d518254f880c000009
    var account = user.accounts.id(newAccount._id);
    console.log("Account" + account); // Never been printed
};

console.log("Account" + account); 從未被打印過。 我不知道會發生什么 我嘗試了許多不同的方法,但是仍然無法弄清楚。 任何幫助,將不勝感激。


用戶集合:

{
    "__v" : 1,
    "_id" : ObjectId("53bcf3e6fbf5adf10c000001"),
    "accounts" : [
        {
            "accountId" : "123456789",
            "type" : "Saving account",
            "balance" : 100,
            "_id" : ObjectId("53bf93d518254f880c000009")
        }
    ]
}

一世

不太確定如何定義Schema或基本上甚至是模型實例,但是實際上所需要做的就是:

var accountSchema = new Schema({
    "accountId": String,
    "type": { "type": String, "enum": ["Saving Account", "Checking Account"] },
    "balance": { "type": Number, "default": 0 }
]);

var userSchema = new Schema({
    "accounts": [accountSchema]
]);

var User = mongoose.model( "User", userSchema );

然后,當您要將帳戶添加到您剛做的用戶時,假設您輸入的內容與第一個變量聲明相匹配:

var input = {
    "accountId": "123456789",
    "type": "Savings Account",
};

User.findByIdAndUpdate(
    userId,
    { "$push": { "accounts": input } },
    function(err,user) {
        // work with result in here
    }
);

這確實繞過了諸如驗證和其他掛鈎之類的事情,但是與MongoDB的通信效率更高。

如果您確實需要驗證和/或其他功能,則可以使用.find()變體並發出.save()方法。

User.findById(userId,function(err,user) {
    if (err) throw err;    // or handle better

    user.accounts.push( input );
    user.save(function(err, user) {
        // more handling
    });
]);

而要修改文檔,您將執行相同的操作。 通過最有效的MongoDB方法:

var input = {
    accountId: "123456789",
    amount: 100
};

User.findOneAndUpdate(
    { "_id": userId, "accounts.accountId": input.accountId },
    { "$inc": { "accounts.$.balance": input.amount } },
    function(err,user) {
        // handle result
    }
);

或者再次需要Mongoose鈎子和/或驗證才能應用:

User.findById(userId,function(err,user) {
    if (err) throw err;   // or handle otherwise

    user.accounts.forEach(function(account) {
        if ( account.accountId === input.accountId )
            account.balance += input.balance;
    });

    user.save(function(err,user) {
        // handle things
    });
);

請記住,這些都是“數組”,您可以用MongoDB方式或JavaScript方式處理它們。 這僅取決於您選擇在何處“驗證”您的輸入。


更多代碼說明用法不正確的地方:

var async = require('async'),
    mongoose = require('mongoose'),
    Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/child');


var accountSchema = new Schema({
  "accountId": String,
  "type": { "type": String },
  "balance": { "type": Number, "default": 0 }
});

var userSchema = new Schema({
  "accounts": [accountSchema]
});

var User = mongoose.model( "User", userSchema );

async.waterfall([

  function(callback) {
    User.create({},function(err,user) {
      if (err) throw err;
      console.log(
        "Created:\n%s\n",
        JSON.stringify( user, undefined, 4 )
      );
      callback(null,user);
    });
  },

  function(user,callback) {
    var account = user.accounts.create({
      "accountId": "123456789",
      "type": "Savings"
    });

    console.log(
      "Account is:\n%s\n",
      JSON.stringify( account, undefined, 4 )
    );

    console.log(
      "User is still:\n%s\n",
      JSON.stringify( user, undefined, 4 )
    );

    user.accounts.push( account );

    console.log(
      "User Changed:\n%s\n",
      JSON.stringify( user, undefined, 4 )
    );

    User.findById(user.id,function(err,saved) {
      if (err) throw err;
      console.log(
        "Persisted is still:\n%s\n",
        saved
      );
      user.save(function(err,user) {
        if (err) throw err;
        callback(null,user,account);
      });
    });

  },

  function(user,account,callback) {

    User.findById(user.id,function(err,saved) {
      if (err) throw err;
      console.log(
        "Persisted is now:\n%s\n",
        saved
      );

      var item = user.accounts.id(account.id);
      console.log(
        "Item is:\n%s\n",
        item
      );
      callback();
    });
  }
],function(err) {
  process.exit();
});

結果:

Created:
{
    "__v": 0,
    "_id": "53c08ab51083d1fe3852becc",
    "accounts": []
}

Account is:
{
    "accountId": "123456789",
    "type": "Savings",
    "_id": "53c08ab51083d1fe3852becd",
    "balance": 0
}

User is still:
{
    "__v": 0,
    "_id": "53c08ab51083d1fe3852becc",
    "accounts": []
}

User Changed: 
{
    "__v": 0,
    "_id": "53c08ab51083d1fe3852becc",
    "accounts": [
        {
            "accountId": "123456789",
            "type": "Savings",
            "_id": "53c08ab51083d1fe3852becd",
            "balance": 0
        }
    ]
}

Persisted is still:
{ _id: 53c08ab51083d1fe3852becc, __v: 0, accounts: [] }

Persisted is now:
{ _id: 53c08ab51083d1fe3852becc,
  __v: 1,
  accounts:
  [ { accountId: '123456789',
      type: 'Savings',
      _id: 53c08ab51083d1fe3852becd,
      balance: 0 } ] }

Item is:
{ accountId: '123456789',
  type: 'Savings',
  _id: 53c08ab51083d1fe3852becd,
  balance: 0 }

暫無
暫無

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

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