.findOneAndUpdate()
के मामले में
या कोई भी .findAndModify()
नेवले के लिए कोर ड्राइवर वेरिएंट, वास्तविक कॉलबैक हस्ताक्षर में "तीन" तर्क होते हैं:
function(err,result,raw)
पहले किसी भी त्रुटि प्रतिक्रिया के साथ, फिर विकल्पों के आधार पर संशोधित या मूल दस्तावेज़ और तीसरा जो जारी किए गए बयान का एक लिखित परिणाम है।
उस तीसरे तर्क को डेटा इस तरह वापस करना चाहिए:
{ lastErrorObject:
{ updatedExisting: false,
n: 1,
upserted: 55e12c65f6044f57c8e09a46 },
value: { _id: 55e12c65f6044f57c8e09a46,
number: 55555555,
country: 'US',
token: "XXX",
appInstalled: true,
__v: 0 },
ok: 1 }
lastErrorObject.updatedExisting
. के रूप में संगत फ़ील्ड के साथ या तो true/false
. होना इस बात पर निर्भर करता है कि कोई अप्सर्ट हुआ है या नहीं। ध्यान दें कि _id
. वाला एक "अपसर्टेड" मान भी होता है नए दस्तावेज़ के लिए प्रतिक्रिया जब यह गुण false
. है , लेकिन तब नहीं जब यह true
हो ।
इस तरह आप तीसरी शर्त पर विचार करने के लिए अपनी हैंडलिंग को संशोधित करेंगे, लेकिन यह केवल कॉलबैक के साथ काम करता है न कि किसी वादे के साथ:
Inbox.model.findOneAndUpdate(
{ "number": req.phone.number },
{
"$set": {
"country": req.phone.country,
"token": hat(),
"appInstalled": true
}
},
{ "new": true, "upsert": true },
function(err,doc,raw) {
if ( !raw.lastErrorObject.updatedExitsing ) {
// do things with the new document created
}
}
);
जहां मैं आपको अपडेट ऑपरेटर्स
का उपयोग करने का दृढ़ता से सुझाव दूंगा। यहां कच्ची वस्तुओं के बजाय, एक कच्ची वस्तु हमेशा पूरे दस्तावेज़ को अधिलेखित कर देगी, फिर भी ऑपरेटर जैसे $set
बस सूचीबद्ध क्षेत्रों को प्रभावित करें।
यह भी ध्यान दें कि कथन से मेल खाने वाला कोई भी "क्वेरी तर्क" नए दस्तावेज़ में स्वचालित रूप से असाइन किया जाता है, जब तक कि उनका मान एक सटीक मिलान है जो नहीं मिला था।
यह देखते हुए कि किसी वादे का उपयोग करने से किसी कारण से अतिरिक्त जानकारी वापस नहीं आती है, तो यह न देखें कि { new: false}
सेट करने के अलावा किसी अन्य वादे के साथ यह कैसे संभव है और मूल रूप से जब कोई दस्तावेज़ वापस नहीं किया जाता है तो यह एक नया होता है।
आपके पास वैसे भी सभी दस्तावेज़ डेटा डालने की उम्मीद है, इसलिए ऐसा नहीं है कि आपको वास्तव में उस डेटा को वापस करने की आवश्यकता है। यह वास्तव में है कि मूल चालक विधियां इसे मूल रूप से कैसे संभालती हैं, और केवल "अपरर्टेड" _id
के साथ प्रतिक्रिया करती हैं मूल्य जब एक अपरर्ट होता है।
यह वास्तव में इस साइट पर चर्चा किए गए एक अन्य मुद्दे के तहत आता है:
क्या वादों को पूरा करने के लिए कई तर्क हो सकते हैं?
जहां यह वास्तव में एक वादा प्रतिक्रिया में कई वस्तुओं के संकल्प के लिए नीचे आता है, जो कि देशी विशिष्टता में सीधे समर्थित नहीं है, लेकिन वहां सूचीबद्ध दृष्टिकोण हैं।
इसलिए यदि आप ब्लूबर्ड वादों को लागू करते हैं और .spread()
. का उपयोग करते हैं वहाँ विधि, तो सब कुछ ठीक है:
var async = require('async'),
Promise = require('bluebird'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/test');
var testSchema = new Schema({
name: String
});
var Test = mongoose.model('Test',testSchema,'test');
Promise.promisifyAll(Test);
Promise.promisifyAll(Test.prototype);
async.series(
[
function(callback) {
Test.remove({},callback);
},
function(callback) {
var promise = Test.findOneAndUpdateAsync(
{ "name": "Bill" },
{ "$set": { "name": "Bill" } },
{ "new": true, "upsert": true }
);
promise.spread(function(doc,raw) {
console.log(doc);
console.log(raw);
if ( !raw.lastErrorObject.updatedExisting ) {
console.log( "new document" );
}
callback();
});
}
],
function(err) {
if (err) throw err;
mongoose.disconnect();
}
);
निश्चित रूप से दोनों वस्तुओं को लौटाता है और आप लगातार तब तक पहुंच सकते हैं:
{ _id: 55e14b7af6044f57c8e09a4e, name: 'Bill', __v: 0 }
{ lastErrorObject:
{ updatedExisting: false,
n: 1,
upserted: 55e14b7af6044f57c8e09a4e },
value: { _id: 55e14b7af6044f57c8e09a4e, name: 'Bill', __v: 0 },
ok: 1 }
यहाँ सामान्य व्यवहार को प्रदर्शित करने वाली एक पूरी सूची है:
var async = require('async'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost/test');
var testSchema = new Schema({
name: String
});
var Test = mongoose.model('Test',testSchema,'test');
async.series(
[
function(callback) {
Test.remove({},callback);
},
function(callback) {
Test.findOneAndUpdate(
{ "name": "Bill" },
{ "$set": { "name": "Bill" } },
{ "new": true, "upsert": true }
).then(function(doc,raw) {
console.log(doc);
console.log(raw);
if ( !raw.lastErrorObject.updatedExisting ) {
console.log( "new document" );
}
callback();
});
}
],
function(err) {
if (err) throw err;
mongoose.disconnect();
}
);
रिकॉर्ड के लिए, मूल चालक के पास स्वयं यह समस्या नहीं है क्योंकि प्रतिक्रिया वस्तु वास्तव में यह एकमात्र वस्तु है जो किसी भी त्रुटि से अलग हो जाती है:
var async = require('async'),
mongodb = require('mongodb'),
MongoClient = mongodb.MongoClient;
MongoClient.connect('mongodb://localhost/test',function(err,db) {
var collection = db.collection('test');
collection.findOneAndUpdate(
{ "name": "Bill" },
{ "$set": { "name": "Bill" } },
{ "upsert": true, "returnOriginal": false }
).then(function(response) {
console.log(response);
});
});
तो यह हमेशा कुछ ऐसा ही होता है:
{ lastErrorObject:
{ updatedExisting: false,
n: 1,
upserted: 55e13bcbf6044f57c8e09a4b },
value: { _id: 55e13bcbf6044f57c8e09a4b, name: 'Bill' },
ok: 1 }