Mongoose यूनिक इंडेक्स काम नहीं कर रहा है!


95

मैं MongoDB को इसके सूचकांक के आधार पर एक डुप्लिकेट मान का पता लगाने की कोशिश कर रहा हूं। मुझे लगता है कि यह MongoDB में संभव है, लेकिन Mongoose आवरण के माध्यम से चीजें टूटती दिखाई देती हैं। तो कुछ इस तरह के लिए:

User = new Schema ({
  email: {type: String, index: {unique: true, dropDups: true}}
})

मैं एक ही ईमेल के साथ 2 उपयोगकर्ताओं को बचा सकता हूं। अरे।

यहाँ एक ही मुद्दा व्यक्त किया गया है: https://github.com/LearnBoost/mongoose/issues/56 , लेकिन वह धागा पुराना है और कहीं नहीं जाता है।

अभी के लिए, मैं उपयोगकर्ता को खोजने के लिए db पर मैन्युअल रूप से कॉल कर रहा हूं। "ईमेल" अनुक्रमित होने के बाद से यह कॉल महंगा नहीं है। लेकिन यह अभी भी अच्छा होगा कि इसे देशी तरीके से संभाला जाए।

क्या किसी के पास इसका कोई समाधान है?


1
बुरी खबर, यह अभी भी mongod v2.4.3 के साथ समस्या है, mongoose v3.6.20
damphat

अनोखा मेरे एक होस्ट पर काम करता है, लेकिन एक ही होस्ट पर बिल्कुल एक ही नोड / मोंगोज़ कोड का उपयोग करके uniques लागू करने में विफल रहता है। होस्ट जो ठीक से काम करता है वह एकल मोंगॉड 3.4.10 चलाता है, वह जो नहीं करता है - मोंगोड 3.2.17 के साथ प्रतिकृति सेट चलाता है। दोनों मेजबानों पर, मैं खरोंच से एक संग्रह बना रहा हूं, इसलिए मौजूदा दुपट्टे एक मुद्दा नहीं हैं। मैंने इस पृष्ठ पर अधिकांश समाधानों की कोशिश की है और जो काम किया है वह था @Isaac पाक से मैंगोज-यूनिक-वैलिडेटर।
मैक्सिम

जवाबों:


95

ऊप्स! आपको सिर्फ मोंगो को रिस्टार्ट करना है।


4
मैं एक ही मुद्दा रहा हूँ, लेकिन मुझे यह पता नहीं चल सकता है कि OSX पर मोंगो को कैसे पुनः आरंभ करें। जब मैं इस प्रक्रिया को मारता हूं, तो यह बस फिर से स्वतः हो जाएगा और अद्वितीय सूचकांक अभी भी काम नहीं कर रहा है ... कोई विचार?
रगुलका

7
आपका क्या मतलब है "उफ़ आपको सिर्फ मोंगो को पुनरारंभ करना है" ?! क्या आप कह रहे हैं कि डेटाबेस को नीचे लाए बिना एक इंडेक्स जोड़ना असंभव है?
andrrk

7
यह सच नहीं है। अनुक्रमणिका जोड़ने के लिए आपको मोंगो को पुनः आरंभ करने की आवश्यकता नहीं है।
जॉनीएचके

1
अनोखी बात के लिए .. मैं mongo को फिर से शुरू करने के लिए .. और यह काम किया .. धन्यवाद!
मुहम्मद अहसन अयाज

2
मैंने पुनः आरंभ करने का प्रयास किया। इसके अलावा reindexing। इसे हल करने के लिए डेटाबेस को छोड़ना पड़ा। समस्या का अनुमान है कि डुप्लिकेट पहले से ही मौजूद है इसलिए इंडेक्स को जोड़ने से पहले एक उत्पादन डीबी में मुझे डुप्लिकेट को हटाने और फिर से पुनरारंभ करने की आवश्यकता होगी?
जूनून

40

ऊप्स! आपको सिर्फ मोंगो को रिस्टार्ट करना है।

और री-इंडेक्स भी:

mongo <db-name>
> db.<collection-name>.reIndex()

परीक्षण में, चूंकि मेरे पास महत्वपूर्ण डेटा नहीं है, आप यह भी कर सकते हैं:

mongo <db-name>
> db.dropDatabase()

16
db.dropDatabase () आपके डेटाबेस को मिटा देता है!
आइजैक पाक

28

मैं एक ही मुद्दे में भाग गया: मैंने emailअपने UserSchemaउपयोगकर्ताओं को पहले से ही db में जोड़ने के बाद क्षेत्र के लिए अद्वितीय बाधा जोड़ी, और अभी भी उपयोगकर्ताओं को डुबाने वाले ईमेलों से बचाने में सक्षम था। मैंने निम्न कार्य करके इसे हल किया:

1) उपयोगकर्ता संग्रह से सभी दस्तावेजों को हटा दें।

2) मोंगो शेल से, कमांड निष्पादित करें: db.users.createIndex({email: 1}, {unique: true})

चरण 1 के बारे में, ध्यान दें कि मोंगो के डॉक्स से:

MongoDB निर्दिष्ट सूचकांक क्षेत्र (ओं) पर एक अद्वितीय सूचकांक नहीं बना सकता है यदि संग्रह में पहले से ही डेटा है जो सूचकांक के लिए अद्वितीय बाधा का उल्लंघन करेगा।

https://docs.mongodb.com/manual/core/index-unique/


11

यह व्यवहार तब भी होता है जब आपने मानगो में कुछ डुप्लिकेट छोड़ दिए हों। जब आपका एप्लिकेशन शुरू होगा, तो Mongo उन्हें Mongo में बनाने का प्रयास करेगा।

इसे रोकने के लिए, आप इस त्रुटि को इस तरह से संभाल सकते हैं:

yourModel.on('index', function(err) {
  if (err?) {
    console.error err
  }
);

10

ठीक है, मैं इसे क्षेत्र पर सूचकांक जोड़कर और अद्वितीय संपत्ति सेट करके मोंगोसल से हल करने में सक्षम था:

db.<collectionName>.ensureIndex({fieldName: 1}, {unique: true});

शेल को इस तरह से जवाब देना चाहिए:

{
    "createdCollectionAutomatically" : false,
    "numIndexesBefore" : 1,
    "numIndexesAfter" : 2,
    "ok" : 1
}

अब मोंगोसल से जल्दी परीक्षण करने के लिए:

var doc = {fieldName: 'abc'};
db.<collectionName>.insert(doc)

देना चाहिए: WriteResult ({"nInserted": 1})

लेकिन जब फिर से दोहरा रहे हैं:

db.<collectionName>.insert(doc)

दे देंगे:

WriteResult({
    "nInserted" : 0,
    "writeError" : {
        "code" : 11000,
        "errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: fuelConsumption.users.$email_1  dup key: { : \"martyna@martycud.com\" }"
    }
})

10

मैंने कुछ इस तरह किया है:

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

const FooSchema = new Schema({
   name: { type: String, required: true, index: true, unique: true }
});

const Foo = mongoose.model('Foo', FooSchema);

Foo.createIndexes();

module.exports = Foo

मैंने कहा कि Foo.createIndexes()जब कोड चलाया जा रहा था तो मुझे निम्नलिखित डीआरसी की चेतावनी मिल रही थी।

(node:21553) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.

मुझे यकीन नहीं है कि अगर Foo.createIndexes()अतुल्यकालिक है, लेकिन AFAIK चीजें ठीक काम कर रही हैं


प्रश्न का एकमात्र उत्तर जो समस्या को हल करता है बजाय उसके चारों ओर घूमता है।
साक्षाम गुप्त

इस जवाब से मुझे मदद मिली। मुझे जो कुछ याद आ रहा था वह index: trueमेरे अनूठे सूचकांक को बनाने के लिए था।
एलसिड

6

प्रलेखन के अनुसार: https://docs.mongodb.com/v2.6/tutorial/modify-an-index/

किसी मौजूदा इंडेक्स को संशोधित करने के लिए, आपको इंडेक्स को ड्रॉप और रीक्रिएट करना होगा।

पुनर्जीवित मत करो!

1 - संग्रह ड्रॉप

db.users.drop()

2 - तालिका को फिर से लिखना

db.users.ensureIndex({email: 1, type: 1}, {unique: true})

इसमें कहा गया है कि ड्रॉप इंडेक्स कलेक्शन नहीं
Zero0Ho

5

आवेदन के स्तर से अद्वितीय सूचकांकों को लागू करते समय मोंगोज़ थोड़ा ढीला होता है; इसलिए, यह या तो डेटाबेस से अपने अद्वितीय सूचक को लागू करने के लिए पसंद किया जाता है mongo cli का उपयोग करके या स्पष्ट रूप से mongoose को बताएं कि आप uniqueअपने UserSchema के बाद कोड की निम्नलिखित पंक्ति लिखकर सूचकांक के बारे में गंभीर हैं :

UserSchema.index({ username: 1, email: 1 }, { unique: true});

यह आपके UserSchema में दोनों क्षेत्रों usernameऔर emailक्षेत्रों पर अद्वितीय सूचकांक लागू करेगा । चीयर्स।


5
पार्टी के लिए थोड़ा देर से, लेकिन क्या अच्छा है एक ओआरएम है कि "अद्वितीय सूचकांक लागू करते समय थोड़ा ढीला"
Imre_G

क्या अच्छा है जो किसी भी तरह से मदद नहीं कर रहे हैं। यह समाधान ठोस और उत्पादन के लिए तैयार है।
इसहाक पाक

4

जब मौसमी एक यूनिक इंडेक्स जोड़ने में नाकाम रहेगा:

  1. संग्रह में पहले से ही समान नाम का एक सूचकांक है
  2. संग्रह में पहले से ही अनुक्रमित फ़ील्ड के डुप्लिकेट के साथ दस्तावेज़ शामिल हैं

पहले मामले में, के साथ सूचकांक को सूचीबद्ध करें db.collection.getIndexes(), और पुराने सूचकांक को छोड़ देंdb.collection.dropIndex("index_name") । जब आप Mongoose एप्लिकेशन को पुनः आरंभ करते हैं तो इसे नए सूचकांक को सही ढंग से जोड़ना चाहिए।

दूसरे मामले में आपको Mongoose एप्लिकेशन को पुनरारंभ करने से पहले डुप्लिकेट को निकालने की आवश्यकता है।


3

नेवला-अद्वितीय-सत्यापनकर्ता

इस प्लगइन का उपयोग कैसे करें:

1) npm स्थापित - save mongoose-unique-validator

2) अपने स्कीमा में इस गाइड का पालन करें:

// declare this at the top
var mongoose = require('mongoose');
var uniqueValidator = require('mongoose-unique-validator');

// exampleSchema = mongoose.Schema({}) etc...

exampleSchema.plugin(uniqueValidator);

// module.exports = mongoose.model(...) etc....

3) आम के तरीके

जैसे तरीकों का उपयोग करते समय findOneAndUpdateआपको इस कॉन्फ़िगरेशन ऑब्जेक्ट को पास करना होगा:

{ runValidators: true, context: 'query' }

ie. User.findOneAndUpdate(
      { email: 'old-email@example.com' },
      { email: 'new-email@example.com' },
      { runValidators: true, context: 'query' },
      function(err) {
        // ...
    }

4) अतिरिक्त विकल्प

  1. असंवेदनशील मामला

    अपने स्कीमा में uniqueCaseInsensitive विकल्प का उपयोग करें

    ie. email: { type: String, index: true, unique: true, required: true, uniqueCaseInsensitive: true }

  2. कस्टम त्रुटि संदेश

    ie. exampleSchema.plugin(uniqueValidator, { message: 'Error, expected {PATH} to be unique.' });

अब आप मोंगो को फिर से शुरू करने, डेटाबेस छोड़ने या इंडेक्स बनाने की चिंता किए बिना अपने स्कीमा में अद्वितीय संपत्ति जोड़ / हटा सकते हैं।

कैविट्स (डॉक्स से):

क्योंकि हम डेटाबेस में कोई दस्तावेज़ मौजूद है या नहीं, इसे सत्यापित करने के लिए async ऑपरेशंस पर भरोसा करते हैं। दो प्रश्नों के लिए एक ही समय में निष्पादित करना संभव है, दोनों को 0 वापस मिलता है, और फिर दोनों MongoDB में सम्मिलित होते हैं।

संग्रह को स्वचालित रूप से बंद करना या एकल कनेक्शन को मजबूर करना, कोई वास्तविक समाधान नहीं है।

हमारे अधिकांश उपयोगकर्ताओं के लिए यह एक समस्या नहीं होगी, लेकिन इसके बारे में जागरूक होने के लिए एक किनारे का मामला है।


2

सबसे नया उत्तर: मेंगोडब को फिर से शुरू करने की कोई आवश्यकता नहीं है, यदि कोलसीटॉन का पहले से ही एक ही नाम इंडेक्स है, तो मोंगोइस फिर से आपके इंडेक्स को फिर से नहीं बनाएगा, इसलिए, कोलीसिटॉन के मौजूदा इंडेक्स को सबसे पहले ड्रॉप करें, और अब, जब आप मॉन्गोज चलाते हैं, तो यह नया इंडेक्स बनाएगा , उपरोक्त प्रक्रिया से मेरी समस्या हल हो गई।


1

आप सूचकांक को छोड़ कर भी इस मुद्दे को हल कर सकते हैं;

आइए मान लें कि आप संग्रह usersऔर फ़ील्ड से अनन्य इंडेक्स निकालना चाहते हैं username, इसे टाइप करें:

db.users.dropIndex('username_1');


1

यदि तालिका / संग्रह खाली है, तो क्षेत्र के लिए अद्वितीय सूचकांक बनाएं:

db.<collection_name>.createIndex({'field':1}, {unique: true})

यदि तालिका / संग्रह खाली नहीं है, तो संग्रह को छोड़ दें और सूचकांक बनाएं:

db.<collection_name>.drop()
db.<collection_name>.createIndex({'field':1}, {unique: true})

अब mongoDB पुनः आरंभ करें।


1

जाँच करें कि स्कीमा में AutoIndex सच है, यह शायद गलत (डिफ़ॉल्ट सत्य) सेट करता है जब आप mongoose.conflect विकल्प का उपयोग करते हैं


1

मुझे थोड़ी देर के लिए एक ही मुद्दे का सामना करना पड़ा और बहुत खोज की और मेरे लिए समाधान createIndexes()कार्य था ।

काश कि मदद करता।

इसलिए कोड ऐसा होगा।

User = new Schema ({
   email: {type: String, unique: true}
});
User.createIndexes();

0

यदि आप autoIndex: falseइस तरह से कनेक्शन विधि में विकल्प का उपयोग कर रहे हैं :

mongoose.connect(CONNECTION_STRING, { autoIndex: false });

जिसे हटाने का प्रयास करें। यदि वह काम नहीं करता है, तो इस धागे में सुझाए गए मोंगोडब को फिर से शुरू करने का प्रयास करें।


0

आप अपने स्कीमा को इस प्रकार परिभाषित कर सकते हैं

User = new Schema ({
  email: {
      type: String,
      unique: true
  }
})

लेकिन शायद यह तब काम नहीं करेगा जब पहले से ही एक दस्तावेज़ है और उसके बाद, आपने उपयोगकर्ता के स्कीमा को बदल दिया है। यदि आप संग्रह को छोड़ना नहीं चाहते हैं तो आप इस उपयोगकर्ता संग्रह के लिए ईमेल पर एक सूचकांक बना सकते हैं। इस कमांड का उपयोग करके आप ईमेल पर एक इंडेक्स बना सकते हैं।

db.User.createIndex({email:1},{unique: true})

या आप केवल संग्रह को छोड़ सकते हैं और उपयोगकर्ता को फिर से जोड़ सकते हैं।
संग्रह छोड़ने के लिए, आप इसे दर्ज कर सकते हैं:

db.User.drop()

0

जब मुझे इस समस्या का सामना करना पड़ा, तो मैंने कई बार डेटाबेस को फिर से शुरू करने की कोशिश की, सर्वर को फिर से शुरू किया और कोई भी तरकीब काम नहीं की। मुझे निम्नलिखित कार्य रोबो 3 टी के माध्यम से मिले:

  1. रोबो 3 टी में, संग्रह खोलने के लिए डेटाबेस पर डबल क्लिक करें
  2. संग्रह को प्रश्न में प्रकट करने के लिए संग्रह खोलें। सुनिश्चित करें कि आपके संग्रह खाली हैं, जिनके साथ शुरू करना है
  3. इंडेक्स फोल्डर पर राइट क्लिक करें। डिफ़ॉल्ट रूप से, आप डिफ़ॉल्ट के _id_रूप में देखेंगे । अब, Add Index चुनें
  4. emailउदाहरण के लिए, ई-मेल फ़ील्ड के लिए एक नाम चुनें
  5. JSON के रूप में कुंजी प्रदान करें। उदाहरण के लिए

    {
       "email": 1
    }
    
  6. यूनिक चेकबॉक्स पर क्लिक करें

  7. सहेजें

यह सुनिश्चित करेगा कि कोई डुप्लिकेट ईमेल MongoDB में सहेजे नहीं गए हैं।


वस्तु {"ईमेल": 1} में यहाँ 1 का क्या अर्थ है?
सिल्वरवरु किरन कुमार

0

सुनिश्चित करें कि आपके संग्रह में आपके द्वारा अनूठे सूचकांक डालने वाले क्षेत्र का कोई अतिरेक नहीं है।

फिर बस अपना ऐप (मोंगोज़) रिस्टार्ट करें। यह केवल चुपचाप सूचकांक को जोड़ता है।


0

संग्रह से सभी दस्तावेजों को हटाना:

db.users.remove({})

और फिर से शुरू, जैसा कि दूसरों ने उल्लेख किया है, मेरे लिए काम किया


0

यदि आपका MongoDB एक सेवा के रूप में काम कर रहा है (इसे खोजने का आसान तरीका है यदि आपको टर्मिनल के माध्यम से mongod.exe फ़ाइल को शुरू किए बिना डेटाबेस से कनेक्ट करने की आवश्यकता नहीं है), तो परिवर्तनों को करने के बाद आपको सेवा और / को पुनः आरंभ करने की आवश्यकता हो सकती है। या अपने डेटाबेस को पूरी तरह से छोड़ दें।

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

Windows खोज बार पर सेवा खोज सेवाओं को फिर से शुरू करने के लिए, MongoDB सेवा ढूंढें, फिर खोलने के लिए डबल क्लिक करें और फिर सेवा शुरू करें।

अगर अन्य तरीके आपके लिए काम नहीं करते हैं, तो मेरा मानना ​​है कि यह काम करेगा।


0

मेरे मामले में मानस पुराना था। मैंने इसे CMD पर पुराना npm चलाकर चेक किया। और 'मोंगोज़' को अपडेट किया।

कृपया बताएं कि क्या आपके लिए भी काम किया है।


आप किस संस्करण का उपयोग कर रहे थे?
बाबू_

0

जब आप अपने डेटाबेस को एप्लिकेशन से जोड़ते हैं तो इस विकल्प को जोड़ें: "audoIndex: true" उदाहरण के लिए मेरे कोड में मैंने ऐसा किया था:

const options = {
// your options go here
...
// this code is the solution
audoIndex: true
}
mongoose.connect(DB_URI, options);

मैंने उस संग्रह को भी गिरा दिया जिसमें मुझे समस्या है और इसे फिर से बनाने के लिए सुनिश्चित करें कि यह काम करेगा। मुझे यह समाधान मिला: https://dev.to/emmysteven/solved-mongoose-unique-index-not-working-45d5 मैंने "पुनः आरंभ MongoDB" जैसे समाधानों की कोशिश की, लेकिन मेरे लिए काम नहीं किया।

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