Mongoose에서 .populate ()를 사용하여 특정 필드를 반환합니다.


82

쿼리를 실행 한 후 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");
      }
    }
  }

답변:


89

"필드 반환"이 무엇을 의미하는지 완전히 명확하지 않지만 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
이것은 나를 위해 작동하지 않습니다. Mongoose 업데이트로 이것이 변경되었는지 아는 사람이 있습니까?
Ninja Coding

1
이것은 나에게도 효과가 없습니다 .populate('model', 'field'). .populate('model', { field: 1}),, 모델의 유무 에 .populate('model', [field])관계없이 시도했지만 응답에서 항상 가득 찬 개체를 얻었습니다. 문서에는 귀하의 답변이 옳다고되어 있지만 작동하도록 할 수 없습니다. 누군가 같은 문제가 있습니까? lean()selectPopulatedPaths: false
mel-mouk

51

채워진 문서에 대해 몇 개의 특정 필드 만 반환되도록하려면 필드 이름 구문을 두 번째 인수로 채우기 메서드에 전달하여이를 수행 할 수 있습니다.

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

Mongoose 채우기 필드 선택 참조


7
잘 작동합니다. 더 많은 필드를 반환 할 수도 있지만 더 많은 필드를 전달해야합니다. -> populate ( 'the_field_to_populate', 'name lastname')
slorenzo

채울 모델이 두 개 이상 있고이를위한 필드를 원하면 어떻게됩니까? populate ( 'users posts', 'name')처럼? 둘 다에 대한 이름을 얻으시겠습니까?
MoDrags

다음과 같은 형식 : Model.findOne ({_ id : 'foo'}). populate ({경로 : 'parent-model', 채우기 : {경로 : 'someProperty', 채우기 : {경로 : 'somePropertyBelow'}}})
dontmentionthebackup

28

이렇게 해보세요 :

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

24

이렇게 해보세요 :

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

여기서 무슨 일이 일어나고 있는지 조금 설명하기 위해 : 중첩 채우기 및 단순 채우기에서 필드를 선택합니다.
Andre Simon

당신은 내 하루 :) 저장
Peshraw H. 아메드

21

이제 할 수있는 일은 다음과 같습니다.

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

당신은 내 일 저장
Thamaraiselvam

3

당신은 시도 :

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("user field to populate","fields to display with spaces between each of them " , "modelName ")

모든 매개 변수는 반전 된 쉼표 여야합니다.

아래는 내가받은 출력입니다. 하위 문서 ID를 채우는 것에 대해 걱정할 필요가없는 한 가지가 더 있습니다.

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