[MONGODB] 몽구스 찾기 / 업데이트 하위 문서
MONGODB몽구스 찾기 / 업데이트 하위 문서
나는 문서 폴더에 대한 다음과 같은 스키마를 가지고 :
var permissionSchema = new Schema({
role: { type: String },
create_folders: { type: Boolean },
create_contents: { type: Boolean }
});
var folderSchema = new Schema({
name: { type: string },
permissions: [ permissionSchema ]
});
그래서, 각 페이지에 대해 나는 많은 권한을 가질 수 있습니다. 내 CMS에서 나는 모든 폴더와 권한을 표시 패널이있다. 관리자는 하나의 권한을 편집하고 저장할 수 있습니다.
나는 쉽게 하나의 권한 수정의 권한 배열로 전체 폴더의 문서를 저장할 수 있습니다. 하지만 (실제 스키마가 훨씬 더 필드가) 내가 이런 짓을 수 있도록 모든 문서를 저장하지 않습니다
savePermission: function (folderId, permission, callback) {
Folder.findOne({ _id: folderId }, function (err, data) {
var perm = _.findWhere(data.permissions, { _id: permission._id });
_.extend(perm, permission);
data.markModified("permissions");
data.save(callback);
});
}
하지만 문제는 파마는 항상 정의되지 것입니다! 나는 "정적"이런 식으로 권한을 가져 오기 위해 노력했다 :
var perm = data.permissions[0];
그것은 잘 작동, 그래서 문제는 밑줄 라이브러리가 권한 배열을 조회 할 수없는 것입니다. 내가 가져온 문서의 하위 문서를 얻을 수있는 더 나은 (그리고 workgin) 방법이 추측 그래서.
어떤 생각?
P.S : 내가 루프 "를"및 [i]를 ._ ID == permission._id을 data.permissions을 확인하지만 난 똑똑한 솔루션을하고자하는 data.permission 배열의 각 항목을 확인 해결, 나는 사람이있다 알아!
해결법
-
==============================
1.그래서 참고로, 몽구스의 기본은이 같은 배열의 데이터를 "포함"할 때 그것의 일부가 자신의 하위 문서 속성을의 당신이 각 배열 항목에 대한 _id 값을 얻을 수 있다는 것입니다. 당신은 실제로 업데이트하려는 항목의 인덱스를 결정하기 위해이 값을 사용할 수 있습니다. 이렇게하여 MongoDB의 방법은 어레이에서 "일치"위치 보유 위치 $ 연산자 변수이다 :
그래서 참고로, 몽구스의 기본은이 같은 배열의 데이터를 "포함"할 때 그것의 일부가 자신의 하위 문서 속성을의 당신이 각 배열 항목에 대한 _id 값을 얻을 수 있다는 것입니다. 당신은 실제로 업데이트하려는 항목의 인덱스를 결정하기 위해이 값을 사용할 수 있습니다. 이렇게하여 MongoDB의 방법은 어레이에서 "일치"위치 보유 위치 $ 연산자 변수이다 :
Folder.findOneAndUpdate( { "_id": folderId, "permissions._id": permission._id }, { "$set": { "permissions.$": permission } }, function(err,doc) { } );
.findOneAndUpdate () 메소드는 수정 된 문서를 반환하거나 반환 된 문서가 필요하지 않은 경우, 그렇지 않으면 당신은 방법으로 () .update를 사용할 수 있습니다. 요부가 "일치"로 업데이트 배열의 요소와 앞서 언급 한 바와 같이 위치 $과 일치하는 "을 식별"이다.
사용자가 지정하는 요소 만이 실제로 서버에 "와이어를 통해"전송되도록 그리고 물론 당신은 $ 세트 연산자를 사용하고 있습니다. 당신은 "점 표기법"와 함께이 더 걸릴 당신이 실제로 업데이트 할 요소를 지정할 수 있습니다. 마찬가지로 :
Folder.findOneAndUpdate( { "_id": folderId, "permissions._id": permission._id }, { "$set": { "permissions.$.role": permission.role } }, function(err,doc) { } );
이 MongoDB를가 제공하는 유연성은 그래서, 당신은 매우 당신이 실제로 문서를 업데이트하는 방법에서 "대상"할 수있는 곳.
이것이 그러나 하는가하는 것은 예 : "후크 사전 저장", "확인"또는 기타로 "우회"당신이 당신의 "몽구스"스키마에 내장했을 수있는 논리이다. 은 "최적의"방법은 MongoDB의 "기능"이며 그것이 어떻게 설계되어 있기 때문이다. 그 자체가이 논리를 통해 "편리 성"래퍼로 시도 몽구스. 당신은 몇 가지 컨트롤 자신을 준비하는 경우에, 다음 업데이트는 최적의 방식으로 만들어 질 수있다.
그래서 가능하면 이렇게 데이터를 "포함"을 유지하고 참조 모델을 사용하지 않을 수 있습니다. 그것은 당신이 동시성에 대해 걱정할 필요가 없습니다 모두 "부모"간단한 업데이트에서 "아이"항목의 원자 갱신 할 수 있습니다. 아마 당신이 처음에 MongoDB를 선택해야하는 이유 중 하나입니다.
-
==============================
2.몽구스의 업데이트 유효성 검사 하위하기 위해, 당신은 스키마 객체로서 '부하'그것을 가지고, 다음 몽구스 자동으로 트리거 검증 및 후크.
몽구스의 업데이트 유효성 검사 하위하기 위해, 당신은 스키마 객체로서 '부하'그것을 가지고, 다음 몽구스 자동으로 트리거 검증 및 후크.
const userSchema = new mongoose.Schema({ // ... addresses: [addressSchema], });
사용자가 하위 문서의 배열이 있다면 몽구스 의해 제공되는 ID () 메소드를 사용하여 원하는 하나를 가져올 수있다. 그럼 당신은 개별적으로 해당 필드를 업데이트하거나 수있는 그런 다음 세트 () 메소드를 사용하여 한 번에 여러 필드를 업데이트 할 경우.
User.findById(userId) .then((user) => { const address = user.addresses.id(addressId); // returns a matching subdocument address.set(req.body); // updates the address while keeping its schema // address.zipCode = req.body.zipCode; // individual fields can be set directly return user.save(); // saves document with subdocuments and triggers validation }) .then((user) => { res.send({ user }); }) .catch(e => res.status(400).send(e));
주 당신이 정말로 사용자 문서를 찾기 위해 사용자 ID를 필요로하지 않는, 다음과 같이 일치 addressId 것을 주소 하위 문서를 가지고있는 하나를 검색하여 그것을 얻을 수 있습니다 :
User.findOne({ 'addresses._id': addressId, }) // .then() ... the same as the example above
MongoDB를에서 하위 문서가 부모 문서가 저장되어있는 경우에만 저장됩니다 것을 기억하십시오.
공식 문서에 주제에 대한 자세한 내용을 읽어 보시기 바랍니다.
-
==============================
3.당신이 분리 수거를하지 않으려면 그냥 folderSchema에 permissionSchema을 포함.
당신이 분리 수거를하지 않으려면 그냥 folderSchema에 permissionSchema을 포함.
var folderSchema = new Schema({ name: { type: string }, permissions: [ { role: { type: String }, create_folders: { type: Boolean }, create_contents: { type: Boolean } } ] });
별도의 컬렉션을해야하는 경우,이 최선의 방법입니다 :
당신은 권한 모델을 할 수 :
var mongoose = require('mongoose'); var PermissionSchema = new Schema({ role: { type: String }, create_folders: { type: Boolean }, create_contents: { type: Boolean } }); module.exports = mongoose.model('Permission', PermissionSchema);
그리고 허가 문서에 대한 참조를 사용하여 폴더 모델. 이 같은 다른 스키마를 참조 할 수 있습니다 :
var mongoose = require('mongoose'); var FolderSchema = new Schema({ name: { type: string }, permissions: [ { type: mongoose.Schema.Types.ObjectId, ref: 'Permission' } ] }); module.exports = mongoose.model('Folder', FolderSchema);
그리고 필드 권한을 채울 몽구스 물어 Folder.findOne (). 채우기를 ( '권한')를 호출합니다.
이제 다음과 같은 :
savePermission: function (folderId, permission, callback) { Folder.findOne({ _id: folderId }).populate('permissions').exec(function (err, data) { var perm = _.findWhere(data.permissions, { _id: permission._id }); _.extend(perm, permission); data.markModified("permissions"); data.save(callback); }); }
합니다 (permission._id가 권한 배열에 실제로있는 경우)가 몽구스로 채워진 이후 파마 필드, 정의되지 않는다.
from https://stackoverflow.com/questions/26156687/mongoose-find-update-subdocument by cc-by-sa and MIT license
'MONGODB' 카테고리의 다른 글
[MONGODB] MongoDB의 레코드 톤 이상 느린 매김 (0) | 2019.12.05 |
---|---|
[MONGODB] MongoDB를 거부 연결 (111) errno를 (0) | 2019.12.05 |
[MONGODB] 자동 MongoDB의에서 삭제 된 공간을 압축? (0) | 2019.12.05 |
[MONGODB] 어떻게하여 MongoDB에서이 스키마를 구현해야합니까? (0) | 2019.12.05 |
[MONGODB] 어떻게 그것을 만든 후 몽구스의 하위 문서를 채우는? (0) | 2019.12.05 |