[MONGODB] 어떻게 몽구스의 문서 upsert / 업데이트하려면 어떻게해야합니까?
MONGODB어떻게 몽구스의 문서 upsert / 업데이트하려면 어떻게해야합니까?
아마도 그것은 시간이 아마도 그것은 나를 스파 스 문서에 익사와 몽구스의 갱신의 개념 주위에 내 머리를 정리 할 수있는 아니에요입니다 :)
여기 거래는 다음과 같습니다
나는 접촉 스키마와 모델 (단축 특성)이 있습니다
var mongoose = require('mongoose'),
Schema = mongoose.Schema;
var mongooseTypes = require("mongoose-types"),
useTimestamps = mongooseTypes.useTimestamps;
var ContactSchema = new Schema({
phone: {
type: String,
index: {
unique: true,
dropDups: true
}
},
status: {
type: String,
lowercase: true,
trim: true,
default: 'on'
}
});
ContactSchema.plugin(useTimestamps);
var Contact = mongoose.model('Contact', ContactSchema);
내가 필요 thusly 히 내 모델을 사용하는 필드를 포함하는, 클라이언트로부터의 요청을 수신 :
mongoose.connect(connectionString);
var contact = new Contact({
phone: request.phone,
status: request.status
});
그리고 지금 우리는이 문제에 도달 :
결론 그래서 모든 나는 시도 후 : 문서의 접촉을 주어, 어떻게 존재하는 경우이를 업데이트 않거나, 그렇지 않을 경우 추가?
시간 내 줘서 고마워.
해결법
-
==============================
1.몽구스는 지금이 기본적으로 findOneAndUpdate와 지원 (MongoDB를 findAndModify 호출).
몽구스는 지금이 기본적으로 findOneAndUpdate와 지원 (MongoDB를 findAndModify 호출).
존재하지 않는 경우 upsert는 = TRUE 옵션은 개체를 만듭니다. 디폴트는 false.
var query = {'username': req.user.username}; req.newData.username = req.user.username; MyModel.findOneAndUpdate(query, req.newData, {upsert: true}, function(err, doc) { if (err) return res.send(500, {error: err}); return res.send('Succesfully saved.'); });
이전 버전에서는 몽구스는이 방법이 후크를 지원하지 않습니다
-
==============================
2.난 그냥 같은 문제를 해결하기 위해 노력 고체 3 시간 불. 특히, 나는 그것이 존재하는 경우 전체 문서를 "대체", 또는 그렇지 않으면 삽입하고 싶었다. 여기에 솔루션입니다 :
난 그냥 같은 문제를 해결하기 위해 노력 고체 3 시간 불. 특히, 나는 그것이 존재하는 경우 전체 문서를 "대체", 또는 그렇지 않으면 삽입하고 싶었다. 여기에 솔루션입니다 :
var contact = new Contact({ phone: request.phone, status: request.status }); // Convert the Model instance to a simple object using Model's 'toObject' function // to prevent weirdness like infinite looping... var upsertData = contact.toObject(); // Delete the _id property, otherwise Mongo will return a "Mod on _id not allowed" error delete upsertData._id; // Do the upsert, which works like this: If no Contact document exists with // _id = contact.id, then create a new doc using upsertData. // Otherwise, update the existing doc with upsertData Contact.update({_id: contact.id}, upsertData, {upsert: true}, function(err{...});
나는이이 문서에 추가 할에 대한 그 정보를 요청하는 몽구스 프로젝트 페이지에 문제를 만들었습니다.
-
==============================
3.당신은에 가까웠다
당신은에 가까웠다
Contact.update({phone:request.phone}, contact, {upsert: true}, function(err){...})
하지만 두 번째 매개 변수는 예를 들어 수정 연산자 객체이어야한다
Contact.update({phone:request.phone}, {$set: { phone: request.phone }}, {upsert: true}, function(err){...})
-
==============================
4.글쎄, 난 충분히없이 대답을 기다렸다. 마지막으로 전체 업데이트 / upsert 접근 방식을 포기하고 갔다 :
글쎄, 난 충분히없이 대답을 기다렸다. 마지막으로 전체 업데이트 / upsert 접근 방식을 포기하고 갔다 :
ContactSchema.findOne({phone: request.phone}, function(err, contact) { if(!err) { if(!contact) { contact = new ContactSchema(); contact.phone = request.phone; } contact.status = request.status; contact.save(function(err) { if(!err) { console.log("contact " + contact.phone + " created at " + contact.createdAt + " updated at " + contact.updatedAt); } else { console.log("Error: could not save contact " + contact.phone); } }); } });
작동합니까? 네. 나는이 행복 있습니까? 아마 아닙니다. 이 DB는 하나 대신 호출합니다. 희망 미래 몽구스 구현은 Model.upsert 기능을 가지고 올 것입니다.
-
==============================
5.아주 우아한 해결책 당신은 약속의 체인을 사용하여 얻을 수 있습니다 :
아주 우아한 해결책 당신은 약속의 체인을 사용하여 얻을 수 있습니다 :
app.put('url', (req, res) => { const modelId = req.body.model_id; const newName = req.body.name; MyModel.findById(modelId).then((model) => { return Object.assign(model, {name: newName}); }).then((model) => { return model.save(); }).then((updatedModel) => { res.json({ msg: 'model updated', updatedModel }); }).catch((err) => { res.send(err); }); });
-
==============================
6.난 그냥이 질문에 대답하기 위해 StackOverflow의 계정을 만들었습니다. fruitlessly 인터 웹을 검색 한 후 난 그냥 뭔가 나 자신을 썼다. 이것은 어떤 몽구스 모델에 적용 할 수 있도록 내가 한 방법이다. 어느 쪽이 기능을 가져 오거나 사용자가 업데이트를하고있는 곳 코드에 직접 추가 할 수 있습니다.
난 그냥이 질문에 대답하기 위해 StackOverflow의 계정을 만들었습니다. fruitlessly 인터 웹을 검색 한 후 난 그냥 뭔가 나 자신을 썼다. 이것은 어떤 몽구스 모델에 적용 할 수 있도록 내가 한 방법이다. 어느 쪽이 기능을 가져 오거나 사용자가 업데이트를하고있는 곳 코드에 직접 추가 할 수 있습니다.
function upsertObject (src, dest) { function recursiveFunc (src, dest) { _.forOwn(src, function (value, key) { if(_.isObject(value) && _.keys(value).length !== 0) { dest[key] = dest[key] || {}; recursiveFunc(src[key], dest[key]) } else if (_.isArray(src) && !_.isObject(src[key])) { dest.set(key, value); } else { dest[key] = value; } }); } recursiveFunc(src, dest); return dest; }
그런 다음 몽구스 문서는 다음을 수행 upsert하기 위해,
YourModel.upsert = function (id, newData, callBack) { this.findById(id, function (err, oldData) { if(err) { callBack(err); } else { upsertObject(newData, oldData).save(callBack); } }); };
이 솔루션은, 당신의 혜택을받을 수 있나요 그러나 2 DB 호출을 요구할 수있다
그냥 소스가 기존의 값을 갖는 경우에도 대상 객체는 항상 소스를 재정의합니다 기억
또한, 배열을 위해, 기존의 객체는 기존 배열의 끝에 값이 유지됩니다 그것을 대체하는 것보다 더 긴 배열이있는 경우. 전체 배열을 upsert하는 쉬운 방법은 당신이 일을하고자하는 것입니다 경우 upsert 전에 빈 배열로 기존의 배열을 설정하는 것입니다.
UPDATE - 2016년 1월 16일 프리미티브 값의 배열이 있다면 몽구스 배열이 "세트"기능을 사용하지 않고 업데이트된다 깨닫지 못하고위한 I은 추가 조건을 밝혔다.
-
==============================
7.나는 하나 개의 모음으로 문서 upsert / 업데이트해야, 내가 한 일은이 같은 새 개체 리터럴을 만드는 것이 었습니다 :
나는 하나 개의 모음으로 문서 upsert / 업데이트해야, 내가 한 일은이 같은 새 개체 리터럴을 만드는 것이 었습니다 :
notificationObject = { user_id: user.user_id, feed: { feed_id: feed.feed_id, channel_id: feed.channel_id, feed_title: '' } };
내가 다른 곳에서 내 데이터베이스에서 가져온 다음 모델에 업데이 트를 호출하는 데이터에서 구성
Notification.update(notificationObject, notificationObject, {upsert: true}, function(err, num, n){ if(err){ throw err; } console.log(num, n); });
이것은 내가 처음으로 스크립트를 실행 한 후 얻을 수있는 출력 :
1 { updatedExisting: false, upserted: 5289267a861b659b6a00c638, n: 1, connectionId: 11, err: null, ok: 1 }
나는 두 번째의 스크립트를 실행할 때이 출력입니다 :
1 { updatedExisting: true, n: 1, connectionId: 18, err: null, ok: 1 }
나는 몽구스 버전 3.6.16을 사용하고 있습니다
-
==============================
8.
app.put('url', function(req, res) { // use our bear model to find the bear we want Bear.findById(req.params.bear_id, function(err, bear) { if (err) res.send(err); bear.name = req.body.name; // update the bears info // save the bear bear.save(function(err) { if (err) res.send(err); res.json({ message: 'Bear updated!' }); }); }); });
여기 몽구스의 업데이트 방법을 해결하는 더 나은 방법을 사용하면 자세한 내용 Scotch.io를 확인할 수 있습니다. 이것은 확실히 나를 위해 일한!
-
==============================
9.이 2.6에 도입 된 버그이며,뿐만 아니라 2.7에 영향을
이 2.6에 도입 된 버그이며,뿐만 아니라 2.7에 영향을
upsert 2.4에서 제대로 작동하는 데 사용
https://groups.google.com/forum/#!topic/mongodb-user/UcKvx4p4hnY https://jira.mongodb.org/browse/SERVER-13843
보세요, 그것은 몇 가지 중요한 정보가 들어 있습니다
그것은 평균 upsert이 작동하지 않는 나던. 여기를 사용하는 방법의 좋은 예입니다 :
User.findByIdAndUpdate(userId, {online: true, $setOnInsert: {username: username, friends: []}}, {upsert: true}) .populate('friends') .exec(function (err, user) { if (err) throw err; console.log(user); // Emit load event socket.emit('load', user); });
-
==============================
10.이 날 위해 일했습니다.
이 날 위해 일했습니다.
app.put ( '/ 학생 / : 아이디'(REQ, 고해상도) => { Student.findByIdAndUpdate (req.params.id, req.body (ERR, 사용자) => { 경우 (ERR) { 반환 고해상도 .STATUS (500) .send ({오류 : "실패"}) }; ({성공 "성공"}) res.send; }); });
-
==============================
11.당신은 단순히 이것으로 기록을 갱신하고 응답 업데이트 된 데이터를 얻을 수 있습니다
당신은 단순히 이것으로 기록을 갱신하고 응답 업데이트 된 데이터를 얻을 수 있습니다
router.patch('/:id', (req, res, next) => { const id = req.params.id; Product.findByIdAndUpdate(id, req.body, { new: true }, function(err, model) { if (!err) { res.status(201).json({ data: model }); } else { res.status(500).json({ message: "not found any relative data" }) } }); });
-
==============================
12.여전히 이익을 위해 후크 지원 "upserting"에 대한 해결책을 찾고 여기에 도착 누군가를 위해, 이것은 내가 테스트 작업을 한 것입니다. 아직 2 DB 호출을 필요로하지만 단일 통화 시도했습니다 무엇보다 훨씬 더 안정적이다.
여전히 이익을 위해 후크 지원 "upserting"에 대한 해결책을 찾고 여기에 도착 누군가를 위해, 이것은 내가 테스트 작업을 한 것입니다. 아직 2 DB 호출을 필요로하지만 단일 통화 시도했습니다 무엇보다 훨씬 더 안정적이다.
// Create or update a Person by unique email. // @param person - a new or existing Person function savePerson(person, done) { var fieldsToUpdate = ['name', 'phone', 'address']; Person.findOne({ email: person.email }, function(err, toUpdate) { if (err) { done(err); } if (toUpdate) { // Mongoose object have extra properties, we can either omit those props // or specify which ones we want to update. I chose to update the ones I know exist // to avoid breaking things if Mongoose objects change in the future. _.merge(toUpdate, _.pick(person, fieldsToUpdate)); } else { toUpdate = person; } toUpdate.save(function(err, updated, numberAffected) { if (err) { done(err); } done(null, updated, numberAffected); }); }); }
-
==============================
13.발전기를 사용할 수있는 경우가 훨씬 더 쉬워집니다 :
발전기를 사용할 수있는 경우가 훨씬 더 쉬워집니다 :
var query = {'username':this.req.user.username}; this.req.newData.username = this.req.user.username; this.body = yield MyModel.findOneAndUpdate(query, this.req.newData).exec();
-
==============================
14.여기에 또한 미들웨어 및 유효성 검사기를 호출하는 동안 / 업데이트를 만들 수있는 간단한 방법입니다.
여기에 또한 미들웨어 및 유효성 검사기를 호출하는 동안 / 업데이트를 만들 수있는 간단한 방법입니다.
Contact.findOne({ phone: request.phone }, (err, doc) => { const contact = (doc) ? doc.set(request) : new Contact(request); contact.save((saveErr, savedContact) => { if (saveErr) throw saveErr; console.log(savedContact); }); })
-
==============================
15.
//Here is my code to it... work like ninj router.param('contractor', function(req, res, next, id) { var query = Contractors.findById(id); query.exec(function (err, contractor){ if (err) { return next(err); } if (!contractor) { return next(new Error("can't find contractor")); } req.contractor = contractor; return next(); }); }); router.get('/contractors/:contractor/save', function(req, res, next) { contractor = req.contractor ; contractor.update({'_id':contractor._id},{upsert: true},function(err,contractor){ if(err){ res.json(err); return next(); } return res.json(contractor); }); }); --
-
==============================
16.이미 멋진, 우리는 플러그인을 작성하고 우리가 .upsert 있도록를 초기화하면 몽구스에 첨부 할 수 테크 가이의 대답을, 여행 다음 () 모든 모델에서 사용할 수 있습니다.
이미 멋진, 우리는 플러그인을 작성하고 우리가 .upsert 있도록를 초기화하면 몽구스에 첨부 할 수 테크 가이의 대답을, 여행 다음 () 모든 모델에서 사용할 수 있습니다.
plugins.js
export default (schema, options) => { schema.statics.upsert = async function(query, data) { let record = await this.findOne(query) if (!record) { record = new this(data) } else { Object.keys(data).forEach(k => { record[k] = data[k] }) } return await record.save() } }
db.js
import mongoose from 'mongoose' import Plugins from './plugins' mongoose.connect({ ... }) mongoose.plugin(Plugins) export default mongoose
그런 다음 User.upsert 같은 작업을 수행 할 수 있습니다 ({_ID : 1}, {foo는 '바'}) 또는 YouModel.upsert ({바 'foo는'}, {값 : 1}) 당신이 원하는 때마다합니다.
-
==============================
17.난 그냥 잠시 후 다시이 문제에 다가서는 듯 아론 마스트로 답변에 따라 플러그인을 게시하기로 결정했다.
난 그냥 잠시 후 다시이 문제에 다가서는 듯 아론 마스트로 답변에 따라 플러그인을 게시하기로 결정했다.
https://www.npmjs.com/package/mongoose-recursive-upsert
몽구스 플러그인으로 사용합니다. 그것은 반복적으로 전달 된 객체를 병합하는 정적 방법을 설정합니다.
Model.upsert({unique: 'value'}, updateObject});
-
==============================
18.
User.findByIdAndUpdate(req.param('userId'), req.body, (err, user) => { if(err) return res.json(err); res.json({ success: true }); });
-
==============================
19.다른 솔루션은 나를 위해 일하지 않는다. 나는 POST 요청을 사용하여 다른 발견이 삽입도 제거 할 필요가있어 요청 본문에 _id 전송되는 경우 데이터를 업데이트하고 있습니다.
다른 솔루션은 나를 위해 일하지 않는다. 나는 POST 요청을 사용하여 다른 발견이 삽입도 제거 할 필요가있어 요청 본문에 _id 전송되는 경우 데이터를 업데이트하고 있습니다.
router.post('/user/createOrUpdate', function(req,res){ var request_data = req.body; var userModel = new User(request_data); var upsertData = userModel.toObject(); delete upsertData._id; var currentUserId; if (request_data._id || request_data._id !== '') { currentUserId = new mongoose.mongo.ObjectId(request_data._id); } else { currentUserId = new mongoose.mongo.ObjectId(); } User.update({_id: currentUserId}, upsertData, {upsert: true}, function (err) { if (err) throw err; } ); res.redirect('/home'); });
-
==============================
20.노드와 나를 위해이 커피 스크립트 작품 - 트릭은 전송 및 클라이언트에서 더 _id가 제공되지 않은 경우이 필요 (업데이트를 대체 할 수 있도록 돌아 왔을 때 삽입하고 추가 할 되돌아갑니다 퇴피 _id GET의, 그 OBJECTID 래퍼의 박탈이다 하나).
노드와 나를 위해이 커피 스크립트 작품 - 트릭은 전송 및 클라이언트에서 더 _id가 제공되지 않은 경우이 필요 (업데이트를 대체 할 수 있도록 돌아 왔을 때 삽입하고 추가 할 되돌아갑니다 퇴피 _id GET의, 그 OBJECTID 래퍼의 박탈이다 하나).
app.post '/new', (req, res) -> # post data becomes .query data = req.query coll = db.collection 'restos' data._id = ObjectID(data._id) if data._id coll.save data, {safe:true}, (err, result) -> console.log("error: "+err) if err return res.send 500, err if err console.log(result) return res.send 200, JSON.stringify result
-
==============================
21.빌드 작업에 마틴 Kuzdowicz 위 기록했다. 나는 몽구스와 JSON 개체의 완전 병합을 사용하여 갱신을 수행하려면 다음을 사용합니다. 이 몽구스 전체 유효성 검사 JSON에서 다른 값에 의존 심지어 하나를 수행 할 수 있습니다 몽구스의 model.save () 함수와 함께. 그것은 deepmerge 패키지 https://www.npmjs.com/package/deepmerge을 필요로한다. 그러나 그것은 매우 가벼운 무게 패키지입니다.
빌드 작업에 마틴 Kuzdowicz 위 기록했다. 나는 몽구스와 JSON 개체의 완전 병합을 사용하여 갱신을 수행하려면 다음을 사용합니다. 이 몽구스 전체 유효성 검사 JSON에서 다른 값에 의존 심지어 하나를 수행 할 수 있습니다 몽구스의 model.save () 함수와 함께. 그것은 deepmerge 패키지 https://www.npmjs.com/package/deepmerge을 필요로한다. 그러나 그것은 매우 가벼운 무게 패키지입니다.
var merge = require('deepmerge'); app.put('url', (req, res) => { const modelId = req.body.model_id; MyModel.findById(modelId).then((model) => { return Object.assign(model, merge(model.toObject(), req.body)); }).then((model) => { return model.save(); }).then((updatedModel) => { res.json({ msg: 'model updated', updatedModel }); }).catch((err) => { res.send(err); }); });
-
==============================
22.위의 글을 읽은 후, 나는이 코드를 사용하기로 결정 :
위의 글을 읽은 후, 나는이 코드를 사용하기로 결정 :
itemModel.findOne({'pid':obj.pid},function(e,r){ if(r!=null) { itemModel.update({'pid':obj.pid},obj,{upsert:true},cb); } else { var item=new itemModel(obj); item.save(cb); } });
R가 null의 경우, 우리는 새 항목을 만들 수 있습니다. 업데이트에 새 항목을 생성하지 않기 때문에 그렇지 않으면 업데이트에 upsert 사용합니다.
from https://stackoverflow.com/questions/7267102/how-do-i-update-upsert-a-document-in-mongoose by cc-by-sa and MIT license
'MONGODB' 카테고리의 다른 글
[MONGODB] 어떻게 쉘 스크립트를 통해 몽고 명령을 실행합니다? (0) | 2019.12.02 |
---|---|
[MONGODB] MongoDB의 컬렉션 모든 문서에 새 필드를 추가 (0) | 2019.12.02 |
[MONGODB] 어떻게하여 MongoDB의 마지막 N 기록을 얻을 수 있습니까? (0) | 2019.12.02 |
[MONGODB] 어떻게하여 MongoDB에서 참조 된 개체는 쿼리합니까? (0) | 2019.12.01 |
[MONGODB] MongoDB의 날짜를 문자열로 변환 (0) | 2019.12.01 |