मूंगोज़ के माध्यम से मोंगो सरणी में आइटम पुश करें


185

मैंने उत्तर की तलाश में एक अच्छा सा बदमाश है, लेकिन मुझे यकीन है कि मैं सही शब्दों के लिए खो गया हूँ वर्णन करने के लिए कि मैं क्या हूँ।

मूल रूप से मेरे पास 'लोगों' नामक एक संग्रह संग्रह है जो कि संग्रह के लिए स्कीमा निम्नानुसार है:

people: {
         name: String, 
         friends: [{firstName: String, lastName: String}]
        }

अब, मेरे पास एक बहुत ही बुनियादी एक्सप्रेस एप्लिकेशन है जो डेटाबेस से जुड़ता है और सफलतापूर्वक एक खाली मित्र सरणी के साथ 'लोगों' को बनाता है।

आवेदन में एक द्वितीयक स्थान में, दोस्तों को जोड़ने के लिए एक फॉर्म है। फॉर्म पहले नाम और अंतिम नाम में लेता है और फिर नाम फ़ील्ड के साथ POST भी उचित लोगों के ऑब्जेक्ट के संदर्भ के लिए।

मुझे जो मुश्किल समय हो रहा है वह एक नया मित्र ऑब्जेक्ट बना रहा है और फिर इसे मित्र सरणी में "पुश" कर रहा है।

मुझे पता है कि जब मैं मोंगो कंसोल के माध्यम से ऐसा करता हूं, तो मैं लुकअप मानदंड के बाद अपने दूसरे तर्क के रूप में $ पुश के साथ अपडेट फ़ंक्शन का उपयोग करता हूं, लेकिन मैं ऐसा करने के लिए मानदंड प्राप्त करने का उपयुक्त तरीका नहीं ढूंढ सकता।

db.people.update({name: "John"}, {$push: {friends: {firstName: "Harry", lastName: "Potter"}}});

अद्यतन: तो, एड्रियन का जवाब बहुत मददगार था। अपने लक्ष्य को पूरा करने के लिए मैंने जो किया वह निम्नलिखित है।

मेरे app.js फ़ाइल में, मैं एक अस्थायी मार्ग का उपयोग कर सेट करता हूं

app.get('/addfriend', users.addFriend);

जहाँ मेरे users.js फ़ाइल में मेरे पास है

exports.addFriend = function (req, res, next)
{
var friend = {"firstName": req.body.fName, "lastName": req.body.lName};
Users.findOneAndUpdate({name: req.user.name}, {$push: {friends: friend}});
};

मुझे लगता है कि मैं संभावित रूप से collection.findOneAndUpdate () का उपयोग कर सकता हूं, लेकिन मुझे यकीन नहीं है कि मैं कहां लागू करूंगा? मेरे मॉडल में?
नेउराक्स

जवाबों:


282

मान लिया जाये कि, var friend = { firstName: 'Harry', lastName: 'Potter' };

आपके पास दो विकल्प हैं:

मॉडल को इन-मेमोरी अपडेट करें, और सेव करें (सादा जावास्क्रिप्ट ऐरे.पश):

person.friends.push(friend);
person.save(done);

या

PersonModel.update(
    { _id: person._id }, 
    { $push: { friends: friend } },
    done
);

मैं हमेशा कोशिश करता हूं और संभव होने पर पहले विकल्प के लिए जाता हूं, क्योंकि यह उन लाभों का अधिक सम्मान करेगा जो मोंगो आपको देता है (हुक, सत्यापन, आदि)।

हालाँकि, यदि आप बहुत से समवर्ती लेखन कर रहे हैं, तो आप दौड़ की स्थितियों से टकराएँगे जहाँ आप हर बार पूरे मॉडल को बदलने और आपके द्वारा जोड़े गए पिछले मित्र को खोने से रोकने के लिए नॉटी वर्जन की त्रुटियों को समाप्त करेंगे। तो केवल पूर्व पर जाएं जब यह बिल्कुल आवश्यक हो।


1
मुझे लगा कि दूसरा विकल्प वास्तव में समवर्ती लेखन सुरक्षा के संदर्भ में सुरक्षित है? क्या आपने गलती से बाद में कहा था जब आप पूर्व कहने के लिए थे?
बजे विल ब्रिकनर

37
हाँ, मैं बस की जाँच की और (नवंबर 2017 में), यह है सुरक्षित नेवला उपयोग करने के लिए updateहै, जबकि समारोह में यह नहीं है सुरक्षित , एक दस्तावेज़ को खोजने के लिए स्मृति में इसे संशोधित, और फिर फोन .save()दस्तावेज़ पर विधि। जब मैं कहता हूं कि एक ऑपरेशन 'सुरक्षित' है, तो इसका मतलब है कि भले ही दस्तावेज़ में एक, दो, या 50 परिवर्तन लागू किए जा रहे हों, वे सभी सफलतापूर्वक लागू किए जाएंगे और अपडेट का व्यवहार आपकी अपेक्षा के अनुरूप होगा। अनिवार्य रूप से इन-मेमोरी हेरफेर असुरक्षित है क्योंकि आप एक आउटडेटेड डॉक्यूमेंट पर काम कर सकते हैं, इसलिए जब आप सेव करते हैं, तो चेंज स्टेप खो जाने के बाद होने वाले बदलाव।
बजे विल ब्रिकनर

2
@Will ब्रिकनर इसके लिए एक सामान्य वर्कफ़्लो है जो आपके तर्क को रिट्री लूप में लपेटने के लिए है: (रिट्रीएबल में भ्रूण, संशोधित, सहेजें) होता है। यदि आपको एक संस्करण संस्करण (आशावादी लॉक अपवाद) वापस मिल जाता है, तो आप उस ऑपरेशन को कुछ बार फिर से आज़मा सकते हैं और हर बार एक नई प्रतिलिपि प्राप्त कर सकते हैं। मैं अभी भी जब संभव हो तो परमाणु अद्यतन पसंद करता हूँ!
एड्रियन श्नाइडर

8
@ZackOfAllTrades ने मुझे भ्रमित किया, लेकिन मेरा मानना ​​है कि कॉलबैक फ़ंक्शन है। let done = function(err, result) { // this runs after the mongoose operation }
उपयोगकर्ता

कॉलबैक में मित्र वस्तु की आईडी कैसे प्राप्त करें?
डी निक्स

41

$ धक्का ऑपरेटर एक सरणी के लिए एक निर्धारित मूल्य जोड़ देता है।

{ $push: { <field1>: <value1>, ... } }

$ पुश अपने तत्व के रूप में मूल्य के साथ सरणी फ़ील्ड जोड़ता है।

उपरोक्त उत्तर सभी आवश्यकताओं को पूरा करता है, लेकिन मुझे निम्नलिखित काम करके यह मिला है

var objFriends = { fname:"fname",lname:"lname",surname:"surname" };
Friend.findOneAndUpdate(
   { _id: req.body.id }, 
   { $push: { friends: objFriends  } },
  function (error, success) {
        if (error) {
            console.log(error);
        } else {
            console.log(success);
        }
    });
)

यह वह है जिसे मैंने काम करने के लिए पाया है, इसलिए मुझे लगता है कि यह 2019 की तारीख तक सबसे अधिक है। सबसे अच्छा जवाब जो मुझे लगता है कि किसी तरह से कमी है और शायद अधूरा / पुराना है।
चीजस टोस्ट

हो सकता है मैं आपको यह बता दूं कि आपको कोड में थोड़ी सी भी त्रुटि हो सकती है। मुझे यह काम करने के लिए मिला क्योंकि मैंने अपनी परियोजना के लिए सही चर रखा। जहाँ आपके पास Friend.findOneAndUpdate () मुझे लगता है कि यह People.findOneAndUpdate () होना चाहिए। यह मूल प्रश्न को ध्यान में रखते हुए अधिक होगा। मैं इसे आपके लिए संपादित कर सकता हूं, लेकिन मैं गलत होने की स्थिति में आप इसे केवल दो बार जांचना चाहूंगा (मैं नोड / एक्सप्रेस के लिए थोड़ा नया हूं)।
चीजस टोस्ट

@CheesusToast मुझे लगता है, अगर मैं गलत हूं, तो आप जवाब बदल सकते हैं। मैंने यह जवाब दिया है जो मेरे लिए ठीक काम कर रहा था। लेकिन अगर आपको यह उत्तर गलत लगता है, तो आप इस उत्तर को बदल सकते हैं और मुझे खुशी होगी यदि आपने मुझे सही किया है :-)।
पार्थ रावल

1
ठीक है, कोई बात नहीं, यह वैसे भी केवल एक छोटा सा संपादन था। यह मेरे लिए एक प्रकार का नाइट-पिकी है क्योंकि दर्शक (मेरे जैसे) ने काम किया होगा, जहां सरणी को वैसे भी धकेला जा रहा था। मुझे अभी भी लगता है कि यह सबसे अच्छा उत्तर होना चाहिए :)
चीज़स टोस्ट

9

$pushदस्तावेज़ को अपडेट करने और किसी सरणी के अंदर नया मान सम्मिलित करने के लिए उपयोग करें ।

लगता है:

db.getCollection('noti').find({})

परिणाम के लिए खोजें:

{
    "_id" : ObjectId("5bc061f05a4c0511a9252e88"),
    "count" : 1.0,
    "color" : "green",
    "icon" : "circle",
    "graph" : [ 
        {
            "date" : ISODate("2018-10-24T08:55:13.331Z"),
            "count" : 2.0
        }
    ],
    "name" : "online visitor",
    "read" : false,
    "date" : ISODate("2018-10-12T08:57:20.853Z"),
    "__v" : 0.0
}

अपडेट करें:

db.getCollection('noti').findOneAndUpdate(
   { _id: ObjectId("5bc061f05a4c0511a9252e88") }, 
   { $push: { 
             graph: {
               "date" : ISODate("2018-10-24T08:55:13.331Z"),
               "count" : 3.0
               }  
           } 
   })

अपडेट के लिए परिणाम:

{
    "_id" : ObjectId("5bc061f05a4c0511a9252e88"),
    "count" : 1.0,
    "color" : "green",
    "icon" : "circle",
    "graph" : [ 
        {
            "date" : ISODate("2018-10-24T08:55:13.331Z"),
            "count" : 2.0
        }, 
        {
            "date" : ISODate("2018-10-24T08:55:13.331Z"),
            "count" : 3.0
        }
    ],
    "name" : "online visitor",
    "read" : false,
    "date" : ISODate("2018-10-12T08:57:20.853Z"),
    "__v" : 0.0
}

2

ऐसा करने का एक आसान तरीका निम्नलिखित है:

var John = people.findOne({name: "John"});
John.friends.push({firstName: "Harry", lastName: "Potter"});
John.save();


-3

मैं इस मुद्दे में भी भाग गया। मेरी नियत थी कि बच्चे को स्कीमा बनाया जाए। अपने मॉडलों के लिए एक उदाहरण के लिए नीचे देखें।

---- व्यक्ति मॉडल

const mongoose = require('mongoose');
const SingleFriend = require('./SingleFriend');
const Schema   = mongoose.Schema;

const productSchema = new Schema({
  friends    : [SingleFriend.schema]
});

module.exports = mongoose.model('Person', personSchema);

*** महत्वपूर्ण: SingleFriend.schema -> स्कीमा के लिए लोअरकेस का उपयोग करना सुनिश्चित करें

--- बाल स्कीमा

const mongoose = require('mongoose');
const Schema   = mongoose.Schema;

const SingleFriendSchema = new Schema({
  Name: String
});

module.exports = mongoose.model('SingleFriend', SingleFriendSchema);

संभवतः पतन का कारण यह है क्योंकि यह आवश्यक नहीं लगता है। पार्थ रावल का जवाब काफी पर्याप्त है।
चेसस टोस्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.