किसी विशिष्ट मान वाले सरणी के साथ दस्तावेज़ ढूँढें


499

अगर मेरे पास यह स्कीमा है ...

person = {
    name : String,
    favoriteFoods : Array
}

... जहां favoriteFoodsसरणी स्ट्रिंग्स के साथ आबादी है। मैं उन सभी व्यक्तियों को कैसे पा सकता हूं जिनके पास "सुशी" है, जो उनके पसंदीदा भोजन के रूप में है।

मैं कुछ के साथ उम्मीद कर रहा था:

PersonModel.find({ favoriteFoods : { $contains : "sushi" }, function(...) {...});

(मुझे पता है कि $containsमोंगोडब में कोई भी नहीं है, बस यह बता रहा हूं कि समाधान जानने से पहले मैं क्या उम्मीद कर रहा था)

जवाबों:


693

जैसा कि favouriteFoodsस्ट्रिंग्स का एक सरल सरणी है, आप सीधे उस फ़ील्ड को क्वेरी कर सकते हैं:

PersonModel.find({ favouriteFoods: "sushi" }, ...);

लेकिन मैं आपके स्कीमा में स्ट्रिंग सरणी को स्पष्ट करने की भी सिफारिश करूंगा:

person = {
    name : String,
    favouriteFoods : [String]
}

प्रासंगिक दस्तावेज यहां देखे जा सकते हैं: https://docs.mongodb.com/manual/tutorial/query-arrays/


19
यह भी काम करता है अगर favouriteFoods:favouriteFoods:[{type:Schema.Types.ObjectId, ref:'Food'}]
k88074

12
जैसे ही कोई व्यक्ति मैंगो जैसे आरडीबीएमएस से आ रहा है, यह पता लगाने के लिए कि इस तरह के समाधान जॉइन और अतिरिक्त तालिकाओं की आवश्यकता के बिना बस काम करते हैं, मुझे आश्चर्य होता है कि मैं जल्द ही मोंगो पर क्यों नहीं शुरू हुआ। लेकिन यह नहीं कहना है कि या तो DBMS दूसरे से बेहतर है - यह आपके उपयोग के मामले पर निर्भर करता है।
इरविन लिम

9
गलती मत करो। यहां तक ​​कि अगर यह तानाशाही की सूची है, तो भी आप इसे इस तरह से क्वेरी कर सकते हैं। नमूना: PersonModel.find({ favouriteFoods.text: "sushi" }, ...); person = { name : String, favouriteFoods : [{text:String}] }
अमीना नुरैनी

3
क्या होता है जब मैं एक एरे को खोजना चाहता हूं जिसमें कम से कम दो तार होते हैं?
एयरो वांग

151

$containsमंगोडब में कोई ऑपरेटर नहीं है ।

आप उस काम के रूप में जॉनीएचके से उत्तर का उपयोग कर सकते हैं। उस मोंगो को शामिल करने के लिए निकटतम सादृश्य है $in, इसका उपयोग करके आपकी क्वेरी इस तरह दिखाई देगी:

PersonModel.find({ favouriteFoods: { "$in" : ["sushi"]} }, ...);

10
क्या ये सही है? $ का उपयोग करते समय मानों की एक सरणी की उम्मीद नहीं है? जैसे {name: {$ in: ["पॉल", "डेव", "लैरी", "एडम"]}}?
लुडविग मैग्नेसन

37
है ना? यह अनावश्यक है। $inका उपयोग तब किया जाता है जब आपके पास कई क्वेरी मान होते हैं और दस्तावेज़ को उनमें से एक से मेल खाना पड़ता है। रिवर्स के लिए (जो इस बारे में सवाल है), जॉनीएचके का जवाब सही है। मैं नीचे जा रहा था, लेकिन मुझे लगता है कि यह उत्तर अन्य लोगों के लिए उपयोगी हो सकता है, जो इस पृष्ठ पर समाप्त होते हैं।
मैल्कमऑन

4
लेकिन इससे मुझे वास्तव में कई मूल्यों के साथ क्वेरी करने में मदद मिली: डी बहुत धन्यवाद!
अलेक्जेंड्रे बॉलीयर

10
धन्यवाद। यह वही है जो मैं वास्तव में देख रहा था, कई मूल्यों की खोज करने का तरीका:PersonModel.find({favouriteFoods: {"$in": ["sushi", "hotdog"]}})
totymedli

@MalcolmOcean सही है, इसमें ऑपरेटर में $ रिवर्स के लिए है, एक सरणी मान के रूप में । क्षेत्र एक सरणी जा रहा है क्या सवाल के बारे में पूछ रहा है। हालांकि, अगर दोनों क्षेत्र और मूल्य सरणियों हैं, तो दोनों इस उत्तर और JohnnyHK के प्रासंगिक जिसका अर्थ है आप में जरूरत $ कर रहे हैं।
tscizzle

87

मुझे लगता है $allकि इस स्थिति में अधिक उपयुक्त होगा। यदि आप उस व्यक्ति की तलाश कर रहे हैं जो सुशी में है तो आप करें:

PersonModel.find({ favoriteFood : { $all : ["sushi"] }, ...})

जैसा कि आप अपनी खोज को और अधिक फ़िल्टर करना चाहते हैं, जैसे:

PersonModel.find({ favoriteFood : { $all : ["sushi", "bananas"] }, ...})

$inOR और $alllike AND की तरह है। इसे देखें: https://docs.mongodb.com/manual/reference/operator/query/all/


क्षमा करें, यह मेरे प्रश्न का गलत उत्तर है। मैं एक सटीक मैच की तलाश नहीं कर रहा हूं, लेकिन केवल उन सरणियों के लिए जिनमें कम से कम मूल्य निर्दिष्ट है।
लुडविग

17
यह आपके प्रश्न का पूरी तरह से मान्य उत्तर है! एक मूल्य के लिए $ सभी या $ का उपयोग करने में कोई अंतर नहीं है। यदि आपके पास "सुशी", "केले" जैसे कई मूल्य हैं, तो $ सभी ऐसे व्यक्तियों की तलाश कर रहे हैं, जिनके पास "सुशी" और "केले" हैं, जो उनके पसंदीदा सरणी में हैं, यदि आप $ का उपयोग ऐसे व्यक्ति कर रहे हैं जिनके पास "सुशी" या "केले" हैं "उनके पसंदीदा भोजन सरणी में।
जोड़ी

हाँ, इसमें कोई $ नहीं है, लेकिन $ सभी इसका एक प्रकार है
डेटिनहॉक

2
सबसे अच्छा जवाब।
निकोले टसेनकोव

65

इस मामले में कि सरणी में उदाहरण के लिए ऑब्जेक्ट हैं यदि favouriteFoodsनिम्न में से ऑब्जेक्ट की एक सरणी है:

{
  name: 'Sushi',
  type: 'Japanese'
}

आप निम्नलिखित प्रश्न का उपयोग कर सकते हैं:

PersonModel.find({"favouriteFoods.name": "Sushi"});

2
यह आसानी से सबसे अच्छा जवाब है। जब आप जल्दी में हों तो उपयोग करना बहुत आसान है।
उबर श्नोक

यह चयनित उत्तर होना चाहिए। यदि आप MongoDB में नेस्टेड दस्तावेज़ों की एक सरणी की क्वेरी के साथ काम कर रहे हैं, तो यह है कि आप इसे कैसे करते हैं। यकीन नहीं होता है कि यह सबसे कुशल है, लेकिन यदि आप ऐसा करने की कोशिश कर रहे हैं, तो आपको इसकी आवश्यकता है।
काइल एल।

32

यदि आपको ऐसे दस्तावेज़ खोजने की आवश्यकता है, जिनमें उप-दस्तावेज़ों की एक सरणी के अंदर NULL तत्व हों, तो मुझे यह क्वेरी मिल गई है जो बहुत अच्छी तरह से काम करती है:

db.collection.find({"keyWithArray":{$elemMatch:{"$in":[null], "$exists":true}}})

यह क्वेरी इस पोस्ट से ली गई है: null मानों के साथ MongoDb क्वेरी ऐरे

यह एक शानदार खोज थी और यह मेरे अपने प्रारंभिक और गलत संस्करण की तुलना में बहुत बेहतर काम करती है (जो केवल अन्य तत्वों के साथ सरणियों के लिए ठीक काम करता है:

.find({
    'MyArrayOfSubDocuments': { $not: { $size: 0 } },
    'MyArrayOfSubDocuments._id': { $exists: false }
})

3

यद्यपि आपके usecase में find with () सबसे प्रभावी है। अभी भी एकत्रीकरण ढांचे का $ मेल है, बड़ी संख्या में प्रविष्टियों की क्वेरी को कम करने और कम संख्या में परिणाम उत्पन्न करने के लिए जो विशेष रूप से समूह बनाने और नई फ़ाइलों को बनाने के लिए आपके लिए मूल्य रखते हैं।

  PersonModel.aggregate([
            { 
                 "$match": { 
                     $and : [{ 'favouriteFoods' : { $exists: true, $in: [ 'sushi']}}, ........ ]  }
             },
             { $project : {"_id": 0, "name" : 1} }
            ]);

मोंगोडब 4.2 के साथ काम नहीं कर रहा है .. कृपया उत्तर दें
विमी

आपको क्या त्रुटि हो रही है, कृपया विस्तार से बताएं?
अमितेश

3

लुकअप_फूड_अरे का इनसे सरणी है।

match_stage["favoriteFoods"] = {'$elemMatch': {'$in': lookup_food_array}}

लुकअप_फूड_अरे का इंसर्जेंस स्ट्रिंग है।

match_stage["favoriteFoods"] = {'$elemMatch': lookup_food_string}

1

लूपबैक 3 के लिए दिए गए सभी उदाहरणों ने मेरे लिए काम नहीं किया, या फिर जितनी तेजी से REST API का उपयोग किया। लेकिन इससे मुझे उस सटीक उत्तर का पता लगाने में मदद मिली जिसकी मुझे ज़रूरत थी।

{"where":{"arrayAttribute":{ "all" :[String]}}}


1
आप एक जीवन रक्षक हैं, धन्यवाद! वह दस्तावेज कहां है और मैंने उसे याद किया? क्या आप कृपया लिंक पोस्ट कर सकते हैं? धन्यवाद।
user2078023

-3

यदि आप जावास्क्रिप्ट के माध्यम से "समाहित" ऑपरेटर जैसे कुछ का उपयोग करना चाहते हैं, तो आप हमेशा उसके लिए एक नियमित अभिव्यक्ति का उपयोग कर सकते हैं ...

जैसे। कहते हैं कि आप एक ग्राहक को "बार्टोलोम्यू" नाम से फिर से प्राप्त करना चाहते हैं

async function getBartolomew() {
    const custStartWith_Bart = await Customers.find({name: /^Bart/ }); // Starts with Bart
    const custEndWith_lomew = await Customers.find({name: /lomew$/ }); // Ends with lomew
    const custContains_rtol = await Customers.find({name: /.*rtol.*/ }); // Contains rtol

    console.log(custStartWith_Bart);
    console.log(custEndWith_lomew);
    console.log(custContains_rtol);
}

-26

मुझे पता है कि यह विषय पुराना है, लेकिन भविष्य के लोगों के लिए जो एक ही प्रश्न को आश्चर्यचकित कर सकते हैं, एक और अविश्वसनीय रूप से अक्षम समाधान करना हो सकता है:

PersonModel.find({$where : 'this.favouriteFoods.indexOf("sushi") != -1'});

यह MongoDB द्वारा सभी अनुकूलन से बचा जाता है ताकि उत्पादन कोड में उपयोग न करें।


जिज्ञासा से बाहर, क्या इस तरह से करने का कोई फायदा है?
लुडविग मैग्यूसन

5
स्वीकृत उत्तर की तुलना में यह अविश्वसनीय रूप से अक्षम है; यह मानगो के सभी अनुकूलन को एक सीधे खोजने के लिए पर्दे के पीछे रखता है जैसा कि स्वीकार किया गया है।
बेखबर

1
हालांकि यह मेरे मामले में मेरे लिए आवश्यक उत्तर है! धन्यवाद "उपयोगकर्ता" :)
वासिल बोरोविक
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.