यह जाँच कर रहा है कि किसी फ़ील्ड में स्ट्रिंग है या नहीं


454

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

कुछ इस तरह:

db.users.findOne({$contains:{"username":"son"}})

क्या यह संभव है?

जवाबों:


693

आप इसे निम्न कोड के साथ कर सकते हैं।

db.users.findOne({"username" : {$regex : ".*son.*"}});

16
ध्यान दें कि यह एक सूचकांक का कुशल उपयोग नहीं करेगा और परिणाम सभी मैचों के लिए स्कैन किया जा रहा है। रेग्युलर एक्सप्रेशंस
स्टेनी जूल

7
@ सेंटनी, फिर आप सूचकांक के कुशल उपयोग करने और एक विकल्प खोजने के लिए क्या सुझाव देते हैं।
ब्लू स्काई

4
@Vish: यदि आपका सामान्य उपयोग मामला किसी क्षेत्र की मुफ्त-पाठ खोज है और आपके पास बड़ी संख्या में दस्तावेज़ हैं, तो मैं अधिक कुशल प्रश्नों के लिए पाठ को टोकन करूँगा। आप एक साधारण पूर्ण-पाठ खोज के लिए मल्टीके का उपयोग कर सकते हैं , या शायद एक अलग संग्रह के रूप में एक उल्टे सूचकांक का निर्माण कर सकते हैं । असीम खोजों या दस्तावेजों के एक छोटे संग्रह के लिए, पूर्ण सूचकांक को स्कैन करना स्वीकार्य (हालांकि इष्टतम नहीं) प्रदर्शन हो सकता है।
1

98
यह एक overkill का एक सा नहीं है? आप क्या चाहते हैं db.users.findOne({"username" : {$regex : "son"}});
जेमीजाग


179

जैसा कि मैंगो शेल रेगेक्स का समर्थन करता है, यह पूरी तरह से संभव है।

db.users.findOne({"username" : /.*son.*/});

यदि हम चाहते हैं कि क्वेरी केस-असंवेदनशील हो, तो हम "i" विकल्प का उपयोग कर सकते हैं, जैसे नीचे दिखाया गया है:

db.users.findOne({"username" : /.*son.*/i});

देखें: http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-RegularExpressions


1
कृपया खोज के लिए नियमित अभिव्यक्ति के उपयोग को प्रदर्शित करने वाला एक कोड स्निपेट शामिल करें। उत्तर में केवल एक लिंक से अधिक जानकारी शामिल होनी चाहिए ...
मैरिक्स

1
चयनित उत्तर मेरे लिए काम नहीं किया, लेकिन यह एक (मैं कर रहा हूँ कमांड के माध्यम से mongo प्रश्नों को निष्पादित कर रहा हूँ) मुझे लगता है कि यह चयनित उत्तर होना चाहिए क्योंकि यह अधिक बहुमुखी प्रतीत होता है।
आर्थर वेबोर

5
चयनित उत्तर में टिप्पणियों की तरह मुझे विश्वास है कि db.users.findOne({"username" : /.*son.*/});ओवरकिल भी हो सकता है और रेगेक्स सरल हो सकता है/son/
आर्थर वेबोर

2
$ रेगेक्स का उपयोग करने से अधिक संक्षिप्त तरीका
लियोनेट चेन

4
इसे केवल उपयोग करने के लिए संपादित करें{ username: /son/ }
व्यैक

150

https://docs.mongodb.com/manual/reference/sql-comparison/

http://php.net/manual/en/mongo.sqltomongo.php

माई एसक्यूएल

SELECT * FROM users WHERE username LIKE "%Son%"

MongoDB

db.users.find({username:/Son/})

8
आपका MongoDB उत्तर अच्छा है; अप्रासंगिक MySQL सलाह को हटाने के लिए अपने प्रश्न को संपादित करने पर विचार करें।
मैरिक्स

31
सभी क्वेरी निकालें या इसे बदलें? एसक्यूएल को सबसे अधिक जाना जाता है, यह MongoDB
झेंग काई

4
@ZhengKai: इस वेबसाइट पर आपको आमतौर पर सीधे पूछे जाने वाले प्रश्न का उत्तर देना चाहिए, केवल विशिष्ट तकनीकों का टैग और अनुरोध किया गया।
मैरिक्स

98
@ व्यक्तिगत रूप से मुझे झेंग का MySQL में समावेश बहुत उपयोगी लगा, क्योंकि इसने रिफाइनेंस का एक बिंदु प्रदान किया।
माइक बार्टलेट

50
मुझे एसक्यूएल संदर्भ भी प्रासंगिक लगा, मुझे लगता है कि इसे रहना चाहिए।
वाइकिंगस्टेव

69

संस्करण 2.4 के अनुसार, आप खोज के लिए $ टेक्स्ट ऑपरेटर की खोज और उपयोग करने के लिए फ़ील्ड (ओं) पर एक टेक्स्ट इंडेक्स बना सकते हैं ।

सबसे पहले, सूचकांक बनाएं:

db.users.createIndex( { "username": "text" } )

फिर, खोज करने के लिए:

db.users.find( { $text: { $search: "son" } } )

बेंचमार्क (~ 150K दस्तावेज़):

  • रेगेक्स (अन्य उत्तर) => 5.6-6.9 सेकंड
  • पाठ खोज => .164 -2018 सेकंड

टिप्पणियाँ:

  • एक संग्रह में केवल एक पाठ सूचकांक हो सकता है। यदि आप किसी स्ट्रिंग क्षेत्र को खोजना चाहते हैं, तो आप वाइल्डकार्ड टेक्स्ट इंडेक्स का उपयोग कर सकते हैं db.collection.createIndex( { "$**": "text" } ):।
  • एक टेक्स्ट इंडेक्स बड़ा हो सकता है। इसमें सम्मिलित किए गए प्रत्येक दस्तावेज़ के लिए प्रत्येक अनुक्रमित फ़ील्ड में प्रत्येक अद्वितीय पोस्ट-स्टेमेड शब्द के लिए एक इंडेक्स प्रविष्टि शामिल है।
  • एक टेक्स्ट इंडेक्स को सामान्य इंडेक्स की तुलना में अधिक समय लगेगा।
  • एक टेक्स्ट इंडेक्स दस्तावेजों में शब्दों की निकटता के बारे में वाक्यांशों या जानकारी को संग्रहीत नहीं करता है। परिणामस्वरूप, जब पूरे संग्रह रैम में फिट बैठता है, तो वाक्यांश क्वेरी बहुत अधिक प्रभावी ढंग से चलेगी।

14
नहीं, इन्फैक्ट टेक्स्ट ऑपरेटर "समाहित" को निष्पादित करने की अनुमति नहीं देता है, इसलिए यह केवल सटीक शब्द मिलान लौटाएगा, वर्तमान में 3.0 के रूप में एकमात्र विकल्प regex का उपयोग करना है, अर्थात db.users.find ({उपयोगकर्ता नाम: / बेटा / i} ) यह एक "बेटा" (केस-
असंवेदनशील

3
जब आप संग्रह में / से दस्तावेज़ जोड़ते या हटाते हैं, तो आपको क्या करना होगा?
जेक विल्सन

प्रश्न का शीर्षक "समाहित" है। पूर्ण पाठ खोज प्रश्न पर लागू नहीं होती है।
डोनाटो

29

चूंकि यह खोज इंजन में पहली हिट में से एक है, और उपरोक्त में से कोई भी MongoDB 3.x के लिए काम नहीं करता है, यहां एक रेगेक्स खोज है जो काम करती है:

db.users.find( { 'name' : { '$regex' : yourvalue, '$options' : 'i' } } )

कोई जरूरत नहीं है और अतिरिक्त सूचकांक या एक जैसे बनाने की जरूरत है।


1
Regexes को पवित्र करने की आवश्यकता है।
सीन

16

यदि आप MongoDB को पायथन के माध्यम से जोड़ रहे हैं तो आपको यहां क्या करना है

db.users.find({"username": {'$regex' : '.*' + 'Son' + '.*'}})

आप 'सोन' के बजाय एक चर नाम का उपयोग कर सकते हैं और इसलिए स्ट्रिंग संघनन।


es2015 में आप backticks {$ regex: .*${value}.*}
माइकल गिल्ड

16

इस कार्य को पूरा करने का सबसे सरल तरीका

यदि आप क्वेरी को केस-संवेदी बनाना चाहते हैं

db.getCollection("users").find({'username':/Son/})

यदि आप चाहते हैं कि क्वेरी केस-असंवेदनशील हो

db.getCollection("users").find({'username':/Son/i})

1
रेगेक्स के साथ चर का उपयोग कैसे करें ??
हिशम

4

आदर्श उत्तर केस-असंवेदनशील के लिए इसके उपयोग सूचकांक i विकल्प

db.users.findOne({"username" : new RegExp(search_value, 'i') });

Regexes को पवित्र करने की आवश्यकता है।
सीन

2

यह काम करना चाहिए

db.users.find({ username: { $in: [ /son/i ] } });

iसिर्फ वहाँ पत्र के एकल मामलों मिलान के प्रतिबंध को रोकने के लिए है।

आप MongoDB प्रलेखन पर $ regex प्रलेखन की जांच कर सकते हैं। यहां एक लिंक है: https://docs.mongodb.com/manual/reference/operator/query/regex/


1

RegExp मैच में HTML टैग्स को कैसे नजरअंदाज करें:

var text = '<p>The <b>tiger</b> (<i>Panthera tigris</i>) is the largest <a href="https://stackoverflow.com/wiki/Felidae" title="Felidae">cat</a> <a href="https://stackoverflow.com/wiki/Species" title="Species">species</a>, most recognizable for its pattern of dark vertical stripes on reddish-orange fur with a lighter underside. The species is classified in the genus <i><a href="https://stackoverflow.com/wiki/Panthera" title="Panthera">Panthera</a></i> with the <a href="https://stackoverflow.com/wiki/Lion" title="Lion">lion</a>, <a href="https://stackoverflow.com/wiki/Leopard" title="Leopard">leopard</a>, <a href="https://stackoverflow.com/wiki/Jaguar" title="Jaguar">jaguar</a>, and <a href="https://stackoverflow.com/wiki/Snow_leopard" title="Snow leopard">snow leopard</a>. It is an <a href="https://stackoverflow.com/wiki/Apex_predator" title="Apex predator">apex predator</a>, primarily preying on <a href="https://stackoverflow.com/wiki/Ungulate" title="Ungulate">ungulates</a> such as <a href="https://stackoverflow.com/wiki/Deer" title="Deer">deer</a> and <a href="https://stackoverflow.com/wiki/Bovid" class="mw-redirect" title="Bovid">bovids</a>.</p>';
var searchString = 'largest cat species';

var rx = '';
searchString.split(' ').forEach(e => {
  rx += '('+e+')((?:\\s*(?:<\/?\\w[^<>]*>)?\\s*)*)';
});

rx = new RegExp(rx, 'igm');

console.log(text.match(rx));

यह संभवतः एक MongoDB एकत्रीकरण फ़िल्टर में बदलना बहुत आसान है।

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