Trả lại các trường nhất định có .populate () từ Mongoose


82

Tôi nhận được trả về một giá trị JSON từ MongoDB sau khi tôi chạy truy vấn của mình. Vấn đề là tôi không muốn trả lại tất cả JSON liên quan đến việc trả lại của mình, tôi đã thử tìm kiếm tài liệu và không tìm thấy cách thích hợp để thực hiện việc này. Tôi đã tự hỏi nếu có thể thì sao, và nếu có thì đâu là cách thích hợp để làm như vậy. Ví dụ: Trong 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"
    }
} 

Cách thích hợp để trả về một trường nếu nó tồn tại cho người dùng, nhưng nếu nó không trả về một trường khác. Đối với ví dụ trên, tôi muốn trả lại [email][address]trường cho RMS và [facebook][address]trường cho Zuckerburg. Đây là những gì tôi đã cố gắng tìm nếu một trường là null, nhưng nó dường như không hoạt động.

 .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");
      }
    }
  }

Câu trả lời:


89

Tôi không hoàn toàn rõ ý của bạn khi "trả về một trường", nhưng bạn có thể sử dụng một lean()truy vấn để bạn có thể tự do sửa đổi kết quả, sau đó điền cả hai trường và xử lý sau kết quả để chỉ giữ lại trường bạn muốn:

.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
điều này không làm việc cho tôi, bất cứ ai biết nếu điều này đã thay đổi với bản cập nhật Mongoose?
Ninja Coding

1
Đây không phải là làm việc cho tôi một trong hai, tôi đã cố gắng .populate('model', 'field'), .populate('model', { field: 1}), .populate('model', [field])có và không có lean()và có và không có selectPopulatedPaths: falsetrên mô hình nhưng tôi luôn luôn có các đối tượng dân cư đầy đủ trong các phản ứng. Tài liệu cho biết câu trả lời của bạn được cho là đúng nhưng tôi không thể làm cho nó hoạt động. Có ai đó đang gặp vấn đề tương tự không?
mel-mouk

51

Nếu bạn chỉ muốn một vài trường cụ thể được trả về cho các tài liệu đã điền, bạn có thể thực hiện điều này bằng cách chuyển cú pháp tên trường làm đối số thứ hai cho phương thức điền.

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

Xem Mongoose điền lựa chọn trường


7
Hoạt động tốt. Bạn cũng có thể trả lại nhiều trường hơn, chỉ bạn phải vượt qua nhiều trường hơn. -> populate ('the_field_to_populate', 'name lastname')
slorenzo

Điều gì sẽ xảy ra nếu bạn có nhiều mô hình để điền và muốn các trường cho chúng? Thích điền ('người dùng đăng bài', 'tên')? Bạn có nhận được tên cho cả hai không?
MoDrags

Một cái gì đó giống như sau: Model.findOne ({_ id: 'foo'}). Populate ({path: 'parent-model', populate: {path: 'someProperty', populate: {path: 'somePropertyBelow'}}})
dontmentionthebackup

28

Cố gắng làm điều này:

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

24

Cố gắng làm điều này:

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);
}

Chỉ để giải thích một chút những gì đang xảy ra ở đây: Đây là để chọn các trường trong một vùng được lồng vào nhau và trong một vùng đơn giản.
Andre Simon

Bạn đã cứu một ngày của tôi :)
Peshraw H. Ahmed

21

Bây giờ những gì bạn có thể làm là:

  .populate('friends', { username: 1, age: 1})

bạn đã cứu ngày của tôi
Thamaraiselvam

3

bạn thử:

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

2

Chỉ để bổ sung cho các câu trả lời ở trên, nếu bạn muốn bao gồm mọi thứ nhưng chỉ loại trừ một số thuộc tính nhất định , bạn có thể làm như sau:

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

0

Xin chào, nó hoạt động với tôi, tôi đã điền trường người dùng bằng cách sử dụng mã điền: --->

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)
    }
}

tôi đang trực tiếp nhận được kết quả. Ở đây, các trường userName, userProfile image là những trường mà tôi đã yêu cầu có chọn lọc và cú pháp để điền là: ->

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

mọi tham số phải được đặt trong dấu phẩy ngược.

Dưới đây là kết quả mà tôi nhận được. Một điều nữa bạn không phải lo lắng về việc điền vào id tài liệu phụ mà bạn sẽ tự động nhận được chúng.

[
    {
        "_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

Trong truy vấn sau, tôi đã truy xuất các bài báo phù hợp với điều kiện show=truedữ liệu title and createdAt được truy xuất cũng truy xuất danh mục bài báo chỉ tiêu đề của danh mục và id của nó.

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

-1

bạn có thể thử sử dụng bên dưới,

 Model
    .find()
    .populate({path: 'foreign_field', ['_id', 'name']}) // only return the Id and Persons name
    ...
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.