Mongooseから.populate()を使用して特定のフィールドを返します


86

クエリを実行した後、MongoDBからJSON値が返されます。問題は、返品に関連するすべてのJSONを返したくないということです。ドキュメントを検索しようとしましたが、これを行う適切な方法が見つかりませんでした。私はそれが可能であるかどうか、もしそうならそれを行う適切な方法は何であるか疑問に思いました。例:DB内

{
    user: "RMS",
    OS: "GNU/HURD",
    bearded: "yes",
    philosophy: {
        software: "FOSS",
        cryptology: "Necessary"
    },
    email: {
        responds: "Yes",
        address: "rms@gnu.org"
    },
    facebook: {}
}

{
    user: "zuckerburg",
    os: "OSX",
    bearded: "no",
    philosophy: {
        software: "OSS",
        cryptology: "Optional"
    },
    email: {},
    facebook: {
        responds: "Sometimes",
        address: "https://www.facebook.com/zuck?fref=ts"
    }
} 

フィールドがユーザーに存在するが、別のフィールドを返さない場合、フィールドを返す適切な方法は何でしょうか。上記の例では[email][address]、RMSの[facebook][address]フィールドとZuckerburgのフィールドを返します。これは、フィールドがnullであるかどうかを確認しようとしましたが、機能していないようです。

 .populate('user' , `email.address`)
  .exec(function (err, subscription){ 
    var key;
    var f;
    for(key in subscription){
      if(subscription[key].facebook != null  ){
          console.log("user has fb");
      }
    }
  }

回答:


90

「フィールドを返す」とはどういう意味か完全にはわかりませんが、lean()クエリを使用して出力を自由に変更し、両方のフィールドにデータを入力して結果を後処理し、必要なフィールドのみを保持することができます。

.lean().populate('user', 'email.address facebook.address')
  .exec(function (err, subscription){ 
    if (subscription.user.email.address) {
        delete subscription.user.facebook;
    } else {
        delete subscription.user.email;
    }
  });

1
これは私にとってはうまくいきません、これがマングースのアップデートで変更されたかどうか誰かが知っていますか?
忍者コーディング

1
これは私が試した、どちらか私のために働いていない.populate('model', 'field').populate('model', { field: 1}).populate('model', [field])ととなしlean()とでとすることなく、selectPopulatedPaths: falseモデルではなく、私は常に応答でフル移入されたオブジェクトを得ました。ドキュメントには、あなたの答えは正しいはずだと書かれていますが、私はそれを機能させることができません。誰かが同じ問題を抱えていますか?
メルムークのせかいりょこう

54

移入されたドキュメントに対していくつかの特定のフィールドのみを返したい場合は、フィールド名の構文を2番目の引数としてpopulateメソッドに渡すことでこれを実現できます。

Model
.findOne({ _id: 'bogus' })
.populate('the_field_to_populate', 'name') // only return the Persons name
...

マングースのデータ入力フィールドの選択を参照してください


8
正常に動作します。より多くのフィールドを返すこともできますが、より多くのフィールドを渡す必要があります。-> Populate( 'the_field_to_populate'、 'name lastname')
slorenzo 2015

入力するモデルが複数あり、それらのフィールドが必要な場合はどうなりますか?Populate( 'users posts'、 'name')のように?両方の名前を教えていただけますか?
MoDrags 2017年

このようなもの:Model.findOne({_ id: 'foo'})。populate({path: 'parent-model'、populate:{path: 'someProperty'、populate:{path: 'somePropertyBelow'}}})
dontmentionthebackup 2017年

28

これを試してください:

User.find(options, '_id user email facebook').populate('facebook', '_id pos').exec(function (err, users) {

26

これを試してください:

applicantListToExport: function (query, callback) {
  this
   .find(query).select({'advtId': 0})
   .populate({
      path: 'influId',
      model: 'influencer',
      select: { '_id': 1,'user':1},
      populate: {
        path: 'userid',
        model: 'User'
      }
   })
 .populate('campaignId',{'campaignTitle':1})
 .exec(callback);
}

1
ここで何が起こっているかを少し説明するだけです。これは、ネストされたデータと単純なデータのフィールドを選択することです。
アンドレシモン

あなたは私の日を救った:)
Peshraw H.Ahmed19年


4

あなたが試す:

Post.find({_id: {$nin: [info._id]}, tags: {$in: info.tags}}).sort({_id:-1})
.populate('uid','nm')
.populate('tags','nm')
.limit(20).exec();

2

上記の回答を補足するために、すべて含めて特定の属性のみを除外したい場合は、次のようにすることができます。

.populate('users', {password: 0, preferences: 0})

0

こんにちは私にとってはそれは私のために働きました私は入力コードを使用してユーザーフィールドに入力しました:--->

async function displayMessage(req,res,next){
    try{
        let data= await Msg.find().populate("user","userName userProfileImg","User")
               if(data===null) throw "Data couldn ot be loaded server error"
        else {
            res.status(200).json(data)
        }
    }   catch(err){
            next(err)
    }
}

私は直接結果を得ています。ここで、フィールドuserName、userProfile imageは、選択的に必要なフィールドであり、populateの構文は次のとおりです:->

 .populate("user field to populate","fields to display with spaces between each of them " , "modelName ")

すべてのパラメーターは引用符で囲む必要があります。

以下は私が受け取る出力です。サブドキュメントIDの入力について心配する必要がないもう1つのことは、自動的にそれらを取得することです。

[
    {
        "_id": "5e8bff324beaaa04701f3bb9",
        "text": "testing message route",
        "user": {
            "_id": "5e8bf062d3c310054cf9f293",
            "userName": "boss",
            "userProfileImg": "img"
        },
        "__v": 0
    },
    {
        "_id": "5e8bff8dd4368a2858e8f771",
        "text": "testing message route second",
        "user": {
            "_id": "5e8bf062d3c310054cf9f293",
            "userName": "boss",
            "userProfileImg": "img"
        },
        "__v": 0
    },
    {
        "_id": "5e8c0c08e9bdb8209829176a",
        "text": "testing message route second",
        "user": {
            "_id": "5e8bf062d3c310054cf9f293",
            "userName": "boss",
            "userProfileImg": "img"
        },
        "__v": 0
    },
    {
        "_id": "5e8c0e0bcb63b12ec875962a",
        "text": "testing message route fourth time",
        "user": {
            "_id": "5e8bf062d3c310054cf9f293",
            "userName": "boss",
            "userProfileImg": "img"
        },
        "__v": 0
    }
]

0

次のクエリではshow=true、取得したデータtitle and createdAt が記事のカテゴリも取得し、カテゴリのタイトルとそのIDのみが条件に一致する記事を取得しました。

let articles = await articleModel
        .find({ show: true }, { title: 1, createdAt: 1 })
        .populate("category", { title: 1, _id: 1 });

-1

以下を使用してみてください、

 Model
    .find()
    .populate({path: 'foreign_field', ['_id', 'name']}) // only return the Id and Persons name
    ...
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.