यह देखने का एकमात्र वास्तविक विश्वसनीय तरीका है कि क्या किसी जैसी किसी चीज़ के लिए अपडेट लागू किया गया था। $खींचें
मूल रूप से लौटाए गए दस्तावेज़ की जांच करना है और यह देखना है कि क्या आप $खींचें
अभी भी है या नहीं।
यह किसी भी "findAndUpdate"
के लिए है
विभिन्न प्रकार की कार्रवाइयां, और इसके लिए एक वैध कारण है और साथ ही यह भी मामला है कि एक सादा .update()
वास्तव में "विश्वसनीय रूप से" आपको बताएगा कि क्या संशोधन वास्तव में किया गया था।
मामलों के माध्यम से चलने के लिए:
लौटाई गई सामग्री की जांच करें
इसमें मूल रूप से लौटाए गए दस्तावेज़ में सरणी को देखना शामिल है ताकि यह देखा जा सके कि हमने जो हटाने के लिए कहा है वह वास्तव में है या नहीं:
var pullId = "5961de06ea264532c684611a";
Office.findByIdAndUpdate(1,
{ "$pull": { "branches": { "_id": pullId } } },
{ "new": true }
).then(office => {
// Check if the supplied value is still in the array
console.log(
"Still there?: %s",
(office.branches.find( b => b._id.toHexString() === pullId))
? true : false
);
}).catch(err => console.error(err))
हम .toHexString()का उपयोग करते हैं। कोड>
ObjectId
. से वास्तविक मान की तुलना करने के लिए चूंकि जावास्क्रिप्ट सिर्फ "ऑब्जेक्ट्स" के साथ "समानता" नहीं करता है। यदि आप किसी ObjectId
को पहले से "कास्ट" की गई किसी चीज़ की आपूर्ति करते हैं, तो आप "बाएं" और "दाएं" दोनों पर जांच करेंगे। मान, लेकिन इस मामले में हम जानते हैं कि अन्य इनपुट एक "स्ट्रिंग" है।
बस .update(), "यह विश्वसनीय है" का उपयोग करें
विचार करने के लिए यहां दूसरा मामला प्रश्न में लाता है यदि आपको वैसे भी लौटाए गए संशोधित डेटा की "वास्तव में आवश्यकता" है। क्योंकि .update()
विधि, विश्वसनीय रूप से एक परिणाम लौटाएगी जो आपको बताएगी कि क्या वास्तव में कुछ भी संशोधित किया गया था:
Office.update(
{ "_id": 1 },
{ "$pull": { "branches": { "_id": pullId } } },
).then(result => {
log(result);
}).catch(err => console.error(err))
जहां परिणाम
यहाँ ऐसा दिखेगा:
{
"n": 1,
"nModified": 1, // <--- This always tells the truth, and cannot lie!
"opTime": {
"ts": "6440673063762657282",
"t": 4
},
"electionId": "7fffffff0000000000000004",
"ok": 1
}
और जिसमें nModified
एक "सच्चा" संकेतक है कि क्या कुछ "वास्तव में अपडेट किया गया" है। इसलिए अगर यह 1
है फिर $खींचें
वास्तव में प्रभाव पड़ा, लेकिन जब 0
वास्तव में सरणी से कुछ भी नहीं हटाया गया था और कुछ भी संशोधित नहीं किया गया था।
ऐसा इसलिए है क्योंकि विधि वास्तव में अद्यतन एपीआई का उपयोग करती है, जिसमें वास्तविक संशोधनों का संकेत देने वाले विश्वसनीय परिणाम होते हैं। वही $set
जिसने वास्तव में मूल्य को नहीं बदला क्योंकि आपूर्ति किया गया मूल्य दस्तावेज़ में पहले से मौजूद मूल्य के बराबर था।
ढूंढें और झूठ को संशोधित करें!
यहां दूसरा मामला आप सोच सकते हैं जब दस्तावेज़ीकरण को बारीकी से देखते हुए वास्तव में "कच्चे परिणाम" का निरीक्षण करना है और देखें कि दस्तावेज़ संशोधित किया गया था या नहीं। इसके लिए विनिर्देश में वास्तव में एक संकेतक है।
समस्या यह है (साथ ही वादों के साथ अधिक काम करने की आवश्यकता है) कि परिणाम वास्तव में सत्य नहीं है:
var bogusId = "5961de06ea264532c684611a"; // We know this is not there!
Promise((resolve,reject) => {
Office.findByIdAndUpdate(1,
{ "$pull": { "branches": { "_id": bogusId } } },
{ "new": true, "passRawResult" },
(err,result,raw) => { // We cannot pass multiple results to a Promise
if (err) reject(err);
resolve({ result, raw }); // So we wrap it!
}
)
})
.then(response => log(response.raw))
.catch(err => console.error(err));
यहां समस्या यह है कि जब हम "जानते हैं" तब भी इसे संशोधित नहीं करना चाहिए, प्रतिक्रिया अन्यथा कहती है:
{
"lastErrorObject": {
"updatedExisting": true,
"n": 1 // <--- LIES! IT'S ALL LIES!!!
},
"value": {
"_id": 1,
"name": "My Office",
"branches": [
{
"address": "Third address",
"isPrincipal": false,
"_id": "5961de06ea264532c6846118"
}
],
"__v": 0
},
"ok": 1,
"_kareemIgnore": true
}
इसलिए कॉलबैक प्रतिक्रिया से "तीसरा" तर्क प्राप्त करने के लिए इतना काम करने के बाद भी, हमें अभी भी अपडेट के बारे में सही जानकारी नहीं मिली।
समाप्त हो रहा है
इसलिए यदि आप इसे "विश्वसनीय रूप से" एक ही अनुरोध के साथ करना चाहते हैं ( और आप नहीं कर सकते हैं कई अनुरोधों के साथ मज़बूती से ऐसा करें क्योंकि दस्तावेज़ बदल सकता है के बीच में! ) तो आपके दो विकल्प हैं:
-
यह देखने के लिए लौटाए गए दस्तावेज़ की जाँच करें कि क्या आप जिस डेटा को हटाना चाहते हैं वह अभी भी है।
-
दस्तावेज़ लौटाना भूल जाइए और विश्वास कीजिए कि
.update()
हमेशा आपको "सच" बताता है;)
आप इनमें से किसका उपयोग करते हैं यह एप्लिकेशन के उपयोग पैटर्न पर निर्भर करता है, लेकिन "विश्वसनीय" परिणाम वापस करने के ये दो अलग-अलग तरीके हैं।
थोड़ा सा लिस्टिंग
तो बस यह सुनिश्चित करने के लिए, यहां एक सूची है जो सभी उदाहरणों के माध्यम से जाती है और दर्शाती है कि वे वास्तव में क्या लौटाते हैं:
const async = require('async'),
mongoose = require('mongoose'),
Schema = mongoose.Schema;
mongoose.Promise = global.Promise;
mongoose.set('debug',true);
mongoose.connect('mongodb://localhost/test');
const branchesSchema = new Schema({
address: String,
isPrincipal: Boolean
});
const officeSchema = new Schema({
_id: Number,
name: String,
branches: [branchesSchema]
},{ _id: false });
const Office = mongoose.model('Office', officeSchema);
function log(data) {
console.log(JSON.stringify(data,undefined,2))
}
const testId = "5961a56d3ffd3d5e19c61610";
async.series(
[
// Clean data
(callback) =>
async.each(mongoose.models,(model,callback) =>
model.remove({},callback),callback),
// Insert some data and pull
(callback) =>
async.waterfall(
[
// Create and demonstrate
(callback) =>
Office.create({
_id: 1,
name: "My Office",
branches: [
{
address: "Some street, that avenue",
isPrincipal: true
},
{
address: "Another address",
isPrincipal: false
},
{
address: "Third address",
isPrincipal: false
}
]
},callback),
// Demo Alternates
(office,callback) =>
async.mapSeries(
[true,false].map((t,i) => ({ t, branch: office.branches[i] })),
(test,callback) =>
(test.t)
? Office.findByIdAndUpdate(office._id,
{ "$pull": { "branches": { "_id": test.branch._id } } },
{ "new": true , "passRawResult": true },
(err,result,raw) => {
if (err) callback(err);
log(result);
log(raw);
callback();
})
: Office.findByIdAndUpdate(office._id,
{ "$pull": { "branches": { "_id": test.branch._id } } },
{ "new": true } // false here
).then(result => {
log(result);
console.log(
"Present %s",
(result.branches.find( b =>
b._id.toHexString() === test.branch._id.toHexString() ))
? true : false
);
callback();
}).catch(err => callback(err)),
callback
)
],
callback
),
// Find and demonstate fails
(callback) =>
async.waterfall(
[
(callback) => Office.findOne({},callback),
(office,callback) =>
async.eachSeries([true,false],(item,callback) =>
(item)
? Office.findByIdAndUpdate(office._id,
{ "$pull": { "branches": { "_id": testId } } },
{ "new": true, "passRawResult": true },
(err,result,raw) => {
if (err) callback(err);
log(result);
log(raw);
callback();
}
)
: Office.findByIdAndUpdate(office._id,
{ "$pull": { "branches": { "_id": testId } } },
{ "new": true }
).then(result => {
console.log(result);
console.log(
"Present %s",
(result.branches.find( b =>
b._id.toHexString() === office.branches[0]._id.toHexString()))
? true : false
);
callback();
})
.catch(err => callback(err)),
callback)
],
callback
),
// Demonstrate update() modified shows 0
(callback) =>
Office.update(
{},
{ "$pull": { "branches": { "_id": testId } } }
).then(result => {
log(result);
callback();
})
.catch(err => callback(err)),
// Demonstrate wrapped promise
(callback) =>
Office.findOne()
.then(office => {
return new Promise((resolve,reject) => {
Office.findByIdAndUpdate(office._id,
{ "$pull": { "branches": { "_id": testId } } },
{ "new": true, "passRawResult": true },
(err,result,raw) => {
if (err) reject(err);
resolve(raw)
}
);
})
})
.then(office => {
log(office);
callback();
})
.catch(err => callback(err))
],
(err) => {
if (err) throw err;
mongoose.disconnect();
}
);
और यह जो उत्पादन करता है:
Mongoose: offices.remove({}, {})
Mongoose: offices.insert({ _id: 1, name: 'My Office', branches: [ { address: 'Some street, that avenue', isPrincipal: true, _id: ObjectId("5961e5211a73e8331b44d74b") }, { address: 'Another address', isPrincipal: false, _id: ObjectId("5961e5211a73e8331b44d74a") }, { address: 'Third address', isPrincipal: false, _id: ObjectId("5961e5211a73e8331b44d749") } ], __v: 0 })
Mongoose: offices.findAndModify({ _id: 1 }, [], { '$pull': { branches: { _id: ObjectId("5961e5211a73e8331b44d74b") } } }, { new: true, passRawResult: true, upsert: false, remove: false, fields: {} })
{
"_id": 1,
"name": "My Office",
"__v": 0,
"branches": [
{
"address": "Another address",
"isPrincipal": false,
"_id": "5961e5211a73e8331b44d74a"
},
{
"address": "Third address",
"isPrincipal": false,
"_id": "5961e5211a73e8331b44d749"
}
]
}
{
"lastErrorObject": {
"updatedExisting": true,
"n": 1
},
"value": {
"_id": 1,
"name": "My Office",
"branches": [
{
"address": "Another address",
"isPrincipal": false,
"_id": "5961e5211a73e8331b44d74a"
},
{
"address": "Third address",
"isPrincipal": false,
"_id": "5961e5211a73e8331b44d749"
}
],
"__v": 0
},
"ok": 1,
"_kareemIgnore": true
}
Mongoose: offices.findAndModify({ _id: 1 }, [], { '$pull': { branches: { _id: ObjectId("5961e5211a73e8331b44d74a") } } }, { new: true, upsert: false, remove: false, fields: {} })
{
"_id": 1,
"name": "My Office",
"__v": 0,
"branches": [
{
"address": "Third address",
"isPrincipal": false,
"_id": "5961e5211a73e8331b44d749"
}
]
}
Present false
Mongoose: offices.findOne({}, { fields: {} })
Mongoose: offices.findAndModify({ _id: 1 }, [], { '$pull': { branches: { _id: ObjectId("5961a56d3ffd3d5e19c61610") } } }, { new: true, passRawResult: true, upsert: false, remove: false, fields: {} })
{
"_id": 1,
"name": "My Office",
"__v": 0,
"branches": [
{
"address": "Third address",
"isPrincipal": false,
"_id": "5961e5211a73e8331b44d749"
}
]
}
{
"lastErrorObject": {
"updatedExisting": true,
"n": 1
},
"value": {
"_id": 1,
"name": "My Office",
"branches": [
{
"address": "Third address",
"isPrincipal": false,
"_id": "5961e5211a73e8331b44d749"
}
],
"__v": 0
},
"ok": 1,
"_kareemIgnore": true
}
Mongoose: offices.findAndModify({ _id: 1 }, [], { '$pull': { branches: { _id: ObjectId("5961a56d3ffd3d5e19c61610") } } }, { new: true, upsert: false, remove: false, fields: {} })
{ _id: 1,
name: 'My Office',
__v: 0,
branches:
[ { address: 'Third address',
isPrincipal: false,
_id: 5961e5211a73e8331b44d749 } ] }
Present true
Mongoose: offices.update({}, { '$pull': { branches: { _id: ObjectId("5961a56d3ffd3d5e19c61610") } } }, {})
{
"n": 1,
"nModified": 0,
"opTime": {
"ts": "6440680872013201413",
"t": 4
},
"electionId": "7fffffff0000000000000004",
"ok": 1
}
Mongoose: offices.findOne({}, { fields: {} })
Mongoose: offices.findAndModify({ _id: 1 }, [], { '$pull': { branches: { _id: ObjectId("5961a56d3ffd3d5e19c61610") } } }, { new: true, passRawResult: true, upsert: false, remove: false, fields: {} })
{
"lastErrorObject": {
"updatedExisting": true,
"n": 1
},
"value": {
"_id": 1,
"name": "My Office",
"branches": [
{
"address": "Third address",
"isPrincipal": false,
"_id": "5961e5211a73e8331b44d749"
}
],
"__v": 0
},
"ok": 1,
"_kareemIgnore": true
}