몽구스 문서를 어떻게 일반 객체로 바꾸나요?


200

나는 몽고 스 발견에서 JSON 인코딩 전에 확장하고 응답으로 보내는 문서를 가지고있다. 문서에 속성을 추가하려고하면 무시됩니다. Object.getOwnPropertyNames(doc)정규 확장을 불가능하게하는 속성은 나타나지 않습니다. 이상한 점은 JSON.parse(JSON.encode(doc))작동하고 올바른 모든 속성을 가진 객체를 반환 한다는 것입니다 . 더 좋은 방법이 있습니까?

답변:


292

몽구스 는의 메소드 를 Model상속받습니다 . 나는 당신이 찾고있는 것이의 결과라고 생각합니다 .DocumenttoObject()doc.toObject()

http://mongoosejs.com/docs/api.html#document_Document-toObject


1
마침내 그것을 얻었다. toObject가 정의되어 있지 않은 사람들은 모델 대신 문서를 호출해야합니다. 즉 modelName._doc.toObject ()
John

1
이것은 괜찮지 만 lean ()이 선호됩니다.
Jason Sebring

Model.find({})docs return 에서 배열을 반환하면이 작업이 수행됩니까? docs.toObject 할 수 있습니까?
jack blank

5
@jackblank 모델 배열이있는 경우 모델을 매핑 할 수 있어야합니다.var docArray = modelArray.map(function(model) { return model.toObject(); });
jmar777

@ jmar777 나는 당신의 제안 이이 답변의 편집에 속한다고 생각합니다.
r3wt

200

이를 수행하는 또 다른 방법은 Mongoose에게 필요한 모든 것을 사용하여 반환 된 문서의 일반 JavaScript 버전이라고 알려주는 것입니다. lean() 쿼리 체인에서 입니다. 그렇게하면 Mongoose는 전체 모델 인스턴스를 만드는 단계를 건너 뛰고 직접 doc수정할 수 있습니다.

MyModel.findOne().lean().exec(function(err, doc) {
    doc.addedProperty = 'foobar';
    res.json(doc);
});

16
@Startec Using lean는 일반적으로 전체 몽구스 문서를 처음 만드는 오버 헤드를 건너 뛰기 때문에 일반적으로 성능이 뛰어납니다.
JohnnyHK

3
당신은 챔피언입니다 :) 내가 틀렸다면 나를 정정하십시오. 그러나 방금받은 문서를 수정하고 저장하지 않으려면 항상 find ()를 lean ()해야합니다 (예를 들어, 문서를 작성하여 고객에게 다시 보냅니다)
Amarsh

1
@Amarsh 예. 스키마에 정의 된 인스턴스 메소드 나 가상이 필요하지 않다고 가정합니다.
JohnnyHK 2016 년

1
bizzare 그러나 ... 이것은 find () 옵션이 될 수 있습니다 ... mongodb에서 문서를 읽고 웹 브라우저로 다시 보내기에는 너무 일반적입니다. find (). lean ()이 실제로 find ()를 먼저 의미하고 결과에 각 요소의 lean ()을 적용하는지 궁금합니다.이 경우 find (). lean () 조합은 실제로 find ()보다 느립니다. 그 자체.
Amarsh

4
@Amarsh 아니요, lean()쿼리 체인 은 쿼리가 실제로 실행되기 전에 옵션을 설정 exec하여 결과가 직접 "간결한"형식이되도록합니다. 호출의 성능에 긍정적 인 영향을 주려면 이 질문 을 참조하십시오 lean.
JohnnyHK

29

속성이 모델에없는 경우 빠른 방법 :

document.set( key,value, { strict: false });


5
그렇습니다 ... 그리고 놀랍게도, 이것이 여전히 유용 할 수 있다고 생각합니다. 예를 들어 모든 객체의 프리미티브를 유지합니다.
alban maillere

이 답변에 감사드립니다, 그것은 내가 찾고 있었던 것입니다 :)
datUser

6

이와 같은 문제를 해결하는 더 좋은 방법은 다음 doc.toObject()과 같습니다.

doc.toObject({ getters: true })

다른 옵션은 다음과 같습니다.

  • getters: 모든 게터 적용 (경로 및 가상 게터)
  • virtuals: 가상 게터 적용 (게터 옵션 무시 가능)
  • minimize: 빈 객체 제거 (기본값은 true)
  • transform: 결과 문서에 반환하기 전에 적용 할 변환 함수
  • depopulate: 채워진 경로를 제거하여 원래 참조로 바꿉니다 (기본값은 false).
  • versionKey: 버전 키 포함 여부 (기본값은 true)

예를 들어 말할 수 있습니다

Model.findOne().exec((err, doc) => {
   if (!err) {
      doc.toObject({ getters: true })
      console.log('doc _id:', doc._id)
   }
})

이제 작동합니다.

자세한 내용은 다음을 참조하십시오 : http://mongoosejs.com/docs/api.html#document_Document-toObject


3

몽구스 문서에서 일반 객체를 얻으려면 _doc다음과 같이 속성을 사용 했습니다.

mongooseDoc._doc  //returns plain json object

나는 시도 toObject했지만 함수, 인수 및 내가 필요없는 다른 모든 것을 나에게 주었다.


3
_처음에 속성이나 메소드에 액세스 하는 것은 이상적인 솔루션이 아닙니다. 린을 사용하면 사건을 해결할 수 있습니다.
Arthur Costa

@ArthurBrito 네. 이상적인 솔루션은 아니지만 여전히 솔루션입니다! . 답을 공감할 필요가 없습니다. 나는 _doc문제에 직면하지 않고 재산을 여러 번 사용 했습니다. 그리고 lean메소드를 사용하면 몽구스 모델 작업을 수행 할 수없는 일반 객체가 제공됩니다.
dd619

네가 옳아. 이상적인 솔루션이 아닌 답을 추가 한 다음 downvote를 제거합니다 (편집하지 않으면 제거 할 수 없음)
Arthur Costa

2

객체를 문자열 화 한 다음 다시 구문 분석하여 일반 객체를 만들 수도 있습니다. 예를 들면 다음과 같습니다.

const obj = JSON.parse(JSON.stringify(mongoObj))
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.