سؤال

على سبيل المثال:

> db.stuff.save({"foo":"bar"});

> db.stuff.find({"foo":"bar"}).count();
1
> db.stuff.find({"foo":"BAR"}).count();
0
هل كانت مفيدة؟

المحلول

يمكنك استخدام regex..

في مثالك سيكون:

db.stuff.find( { foo: /^bar$/i } );

يجب أن أقول، رغم ذلك، ربما يمكنك فقط أسفل (أو UPCAS) القيمة في الطريق بدلا من تكبد تكلفة إضافية في كل مرة تجدها. من الواضح أن هذا لن يعمل لأسماء الناس، ولكن ربما استخدم الحالات مثل العلامات.

نصائح أخرى

تحديث:

الجواب الأصلي هو الآن عفا عليها الزمن. يدعم MongoDB الآن البحث الكامل النص الكامل، مع العديد من الميزات.

الإجابة الأصلية:

تجدر الإشارة إلى أن البحث مع غير حساس لحالة Regex / يعني أن Mongodb لا يمكن البحث عن طريق الفهرس، لذلك استفسارات ضد مجموعات البيانات الكبيرة يمكن أن يستغرق وقتا طويلا.

حتى مع مجموعات البيانات الصغيرة، فإنه ليس فعالا للغاية. يمكنك الحصول على وحدة المعالجة المركزية أكبر بكثير من أوامر الاستعلام الخاصة بك، والتي يمكن أن تصبح مشكلة إذا كنت تحاول تحقيق المقياس.

كبديل، يمكنك تخزين نسخة كبيرة والبحث عن ذلك. على سبيل المثال، لدي جدول مستخدم لديه اسم مستخدم هو حالة مختلطة، ولكن المعرف هو نسخة كبيرة من اسم المستخدم. هذا يضمن الازدواجية الحساسة لحالة الأحرف أمر مستحيل (وجود كلا من "foo" و "foo" لن يسمح)، ويمكنني البحث عن طريق معرف = اسم المستخدم.

إذا كان حقلك كبيرا، مثل هيئة الرسائل، فربما تكون البيانات المكررة ليست خيارا جيدا. أعتقد أن استخدام مفهرس غالب مثل Apache Lucene هو الخيار الأفضل في هذه الحالة.

ضع في اعتبارك المثال السابق:

db.stuff.find( { foo: /bar/i } );

سوف يسبب كل إدخالات تحتوي على شريط لتتناسب مع الاستعلام (Bar1، Barxyz، OpenBar)، قد يكون خطيرا جدا على البحث عن اسم المستخدم على وظيفة المصادقة ...

قد تحتاج إلى جعلها تطابق فقط مصطلح البحث فقط باستخدام بناء جملة Regexp المناسب على النحو التالي:

db.stuff.find( { foo: /^bar$/i } );

يرى http://www.regular-expressions.info/ للحصول على بناء جملة على التعبيرات العادية

إذا كنت بحاجة إلى إنشاء RegexP من متغير، فهذه طريقة أفضل بكثير للقيام بذلك: https://stackoverflow.com/a/10728069/309514.

يمكنك بعد ذلك القيام بشيء مثل:

var string = "SomeStringToFind";
var regex = new RegExp(["^", string, "$"].join(""), "i");
// Creates a regex of: /^SomeStringToFind$/i
db.stuff.find( { foo: regex } );

هذا له هذه الفائدة تكون أكثر برمجة أو يمكنك الحصول على زيادة في الأداء من خلال تجميعها في وقت مبكر إذا كنت تعيد استخدامها كثيرا.

بدءا من MongoDB، فإن الطريقة الموصى بها لإجراء عمليات بحث غير حساسة سريعة هي استخدام أ مؤشر حالة غير حساسة.

أنا شخصيا أرسلت عبر البريد الإلكتروني أحد المؤسسين لإرضاء هذا العمل، وحدث ذلك! لقد كان القضية على جيرا منذ عام 2009, وقد طلب الكثيرون الميزة. وإليك كيف يعمل:

يتم إنشاء مؤشر غير حساس للحالة من خلال تحديد أ التجميع مع قوة إما 1 أو 2. يمكنك إنشاء مؤشر غير حساس مثل هذا:

db.cities.createIndex(
  { city: 1 },
  { 
    collation: {
      locale: 'en',
      strength: 2
    }
  }
);

يمكنك أيضا تحديد تجميع افتراضي لكل مجموعة عند إنشاءها:

db.createCollection('cities', { collation: { locale: 'en', strength: 2 } } );

في كلتا الحالتين، من أجل استخدام مؤشر غير حساس للحالة، تحتاج إلى تحديد نفس الترتيب في find العملية التي تم استخدامها عند إنشاء الفهرس أو المجموعة:

db.cities.find(
  { city: 'new york' }
).collation(
  { locale: 'en', strength: 2 }
);

سيعود هذا "نيويورك"، "نيويورك"، "نيويورك"، إلخ.

الملاحظات الأخرى

  • الإجابات التي تشير إلى استخدامها البحث النص الكامل مخطئ في هذه الحالة (وربما خطير). كان السؤال حول إجراء استفسار غير حساس للحالة، على سبيل المثال username: 'bill' مطابقة BILL أو Bill, ، ليس استعلام بحث نصي كامل، مما سيتطابق أيضا stemmed كلمات bill, ، مثل Bills, billed إلخ.
  • الإجابات التي تشير إلى استخدام تعبيرات منتظمة بطيئة، لأنه حتى مع الفهارس، تنص الوثائق:

    "لا يمكن استخدام استعلامات التعبير المنتظمة غير الحساسة عموما الفهارس بشكل فعال. تطبيق Regex $ غير مدرك، غير قادر على استخدام فهارس غير حساسة للحالة."

    $regex الإجابات تدير أيضا خطر حقن إدخال المستخدم.

db.zipcodes.find({city : "NEW YORK"}); // Case-sensitive
db.zipcodes.find({city : /NEW york/i}); // Note the 'i' flag for case-insensitivity

TL؛ دكتور

الطريقة الصحيحة للقيام بذلك في مونغو

لا تستخدم regexp.

اذهب الطبيعية واستخدام فهرسة mongodb في منذرز، والبحث

الخطوة 1 :

db.articles.insert(
   [
     { _id: 1, subject: "coffee", author: "xyz", views: 50 },
     { _id: 2, subject: "Coffee Shopping", author: "efg", views: 5 },
     { _id: 3, subject: "Baking a cake", author: "abc", views: 90  },
     { _id: 4, subject: "baking", author: "xyz", views: 100 },
     { _id: 5, subject: "Café Con Leche", author: "abc", views: 200 },
     { _id: 6, subject: "Сырники", author: "jkl", views: 80 },
     { _id: 7, subject: "coffee and cream", author: "efg", views: 10 },
     { _id: 8, subject: "Cafe con Leche", author: "xyz", views: 10 }
   ]
)

الخطوة 2 :

بحاجة إلى إنشاء فهرس على أيهما نص الحقل الذي تريد البحث فيه، دون فهرسة الاستعلام سيكون بطيئا للغاية

db.articles.createIndex( { subject: "text" } )

الخطوه 3 :

db.articles.find( { $text: { $search: "coffee",$caseSensitive :true } } )  //FOR SENSITIVITY
db.articles.find( { $text: { $search: "coffee",$caseSensitive :false } } ) //FOR INSENSITIVITY
db.company_profile.find({ "companyName" : { "$regex" : "Nilesh" , "$options" : "i"}});

Mongo (الإصدار الحالي 2.0.0) لا يسمح عمليات البحث غير الحساسة للحالة ضد الحقول المفهرسة - انظر وثائقهم. وبعد للحقول غير المفهرسة، يجب أن تكون Regexes المدرجة في الإجابات الأخرى جيدة.

أفضل طريقة هي في اللغة التي تختارها ، عند إنشاء نموذج المجمع على الأشياء الخاصة بك ، يجب حفظ() طريقة من خلال تكرار مجموعة من الحقول التي سيتم البحث في هذا أيضا مفهرس;هذه مجموعة من المجالات ينبغي أن يكون صغيرة نظيراتها التي تستخدم بعد ذلك في البحث.

في كل مرة حفظ الكائن مرة أخرى ، صغيرة خصائص ثم يتم فحص و تحديث مع أي تغييرات في الخصائص الرئيسية.هذا سوف تجعل من ذلك يمكنك البحث بكفاءة ، ولكن إخفاء العمل الإضافي في حاجة إلى تحديث lc الحقول في كل مرة.

الحالة الأدنى المجالات يمكن أن يكون المفتاح:القيمة مخزن كائن أو مجرد اسم الحقل مع مسبوقة lc_.أنا استخدم واحد ثاني لتبسيط الاستعلام عن (عميق كائن الاستعلام يمكن أن يكون مربكا في بعض الأحيان).

ملاحظة:كنت تريد أن مؤشر lc_ حقول المجالات الرئيسية فهي على الخروج من.

لنفترض أنك تريد البحث في "العمود" في "الجدول" وتريد حالة البحث Insenstive. الطريقة الأفضل والفعالة هي على النحو التالي؛

//create empty JSON Object
mycolumn = {};

//check if column has valid value
if(column) {
    mycolumn.column = {$regex: new RegExp(column), $options: "i"};
}
Table.find(mycolumn);

فوق الرمز يضيف فقط قيمة البحث ك Regex والبحث في معايير Insensitve مجموعة مع "I" كخيار.

أتمنى لك كل خير.

شيء مهم للغاية يجب وضعه في الاعتبار عند استخدام استعلام يستند إلى Regex - عند القيام بذلك لنظام تسجيل الدخول، الهروب من كل شخصية أنت تبحث عنها، ولا تنسى مشغلي ^ و $. لوش لديه وظيفة لطيفة لهذا, ، يجب أن تستخدمه بالفعل:

db.stuff.find({$regex: new RegExp(_.escapeRegExp(bar), $options: 'i'})

لماذا ا؟ تخيل المستخدم يدخل .* كما اسم المستخدم الخاص به. من شأنها أن تطابق جميع أسماء المستخدمين، مما يتيح تسجيل الدخول عن طريق تخمين كلمة مرور مستخدم فقط.

باستخدام Mongoose هذا عملت بالنسبة لي:

var find = function(username, next){
    User.find({'username': {$regex: new RegExp('^' + username, 'i')}}, function(err, res){
        if(err) throw err;
        next(null, res);
    });
}

تم تقديم إطار التجميع في MongoDB 2.2. يمكنك استخدام مشغل السلسلة "$ strcasecmp" لإجراء مقارنة غير حساسة للحالة بين السلاسل. أكثر موصى به وأسهل من استخدام Regex.

إليك الوثيقة الرسمية على مشغل قيادة التجميع: https://docs.mongodb.com/manual/Reference/Operator/agregation/gercasecmp/#exp._s_strcasecmp. .

يمكنك استخدام مؤشرات حساسة للحالة:

المثال التالي ينشئ مجموعة مع عدم وجود ترتيب افتراضي، ثم يضيف فهرس على حقل الاسم مع مجموعة غير حساسة للحالة. المكونات الدولية ل Unicode

/* strength: CollationStrength.Secondary
* Secondary level of comparison. Collation performs comparisons up to secondary * differences, such as diacritics. That is, collation performs comparisons of 
* base characters (primary differences) and diacritics (secondary differences). * Differences between base characters takes precedence over secondary 
* differences.
*/
db.users.createIndex( { name: 1 }, collation: { locale: 'tr', strength: 2 } } )

لاستخدام الفهرس، يجب أن تحدد الاستعلامات نفس الترتيب.

db.users.insert( [ { name: "Oğuz" },
                            { name: "oğuz" },
                            { name: "OĞUZ" } ] )

// does not use index, finds one result
db.users.find( { name: "oğuz" } )

// uses the index, finds three results
db.users.find( { name: "oğuz" } ).collation( { locale: 'tr', strength: 2 } )

// does not use the index, finds three results (different strength)
db.users.find( { name: "oğuz" } ).collation( { locale: 'tr', strength: 1 } )

أو يمكنك إنشاء مجموعة مع الترتيب الافتراضي:

db.createCollection("users", { collation: { locale: 'tr', strength: 2 } } )
db.users.createIndex( { name : 1 } ) // inherits the default collation

للبحث عن متغير والهروب منه:

const escapeStringRegexp = require('escape-string-regexp')
const name = 'foo'
db.stuff.find({name: new RegExp('^' + escapeStringRegexp(name) + '$', 'i')})   

يحمي النزوب من المتغير الاستعلام من الهجمات مع ". *" أو غيرها من Regex.

Escape-string-regexp

لقد قمت بإنشاء Func بسيط للحالة غير حساسة Regex، والتي أستخدمها في مرشحي.

private Func<string, BsonRegularExpression> CaseInsensitiveCompare = (field) => 
            BsonRegularExpression.Create(new Regex(field, RegexOptions.IgnoreCase));

ثم تقوم ببساطة بتصفية في حقل كما يلي.

db.stuff.find({"foo": CaseInsensitiveCompare("bar")}).count();

باستخدام مرشح يعمل بالنسبة لي في C #.

string s = "searchTerm";
    var filter = Builders<Model>.Filter.Where(p => p.Title.ToLower().Contains(s.ToLower()));
                var listSorted = collection.Find(filter).ToList();
                var list = collection.Find(filter).ToList();

قد يستخدم هذا الفهرس لأنني أعتقد أن الأساليب تسمى بعد أن يحدث الإعادة لكنني لم أختبر ذلك بعد.

هذا يتجنب أيضا مشكلة

var filter = Builders<Model>.Filter.Eq(p => p.Title.ToLower(), s.ToLower());

هذا mongodb سوف يفكر p.title.tolower () هو خاصية ولن خريطة بشكل صحيح.

لأي شخص يستخدم Golang ويرد أن يكون لديك تطبيق نصوص كامل الحساسة مع MongoDB و MGO مكتبة godoc globalsign.

collation := &mgo.Collation{
    Locale:   "en",
    Strength: 2, 
}


err := collection.Find(query).Collation(collation)

يستخدم regexp.، في حالة عدم عمل أي خيارات أخرى من أجلك، فإن RegExp هو خيار جيد. يجعل حساسة حالة السلسلة.

var username = new RegExp("^" + "John" + "$", "i");;

استخدم اسم المستخدم في استفسارات، ثم القيام به.

آمل أن تعمل من أجلك أيضا. أتمنى لك كل خير.

كما ترون في مستندات Mongo - منذ الإصدار 3.2 $text الفهرس هو غير حساس لحالة الأحرف بشكل افتراضي: https:/docs.mongodb.com/manual/core/index-text/#text-index-case-senivity.

إنشاء فهرس النص و استخدام مشغل النص $ في استفسارك.

تم اختبارها في عمليات البحث عن السلسلة

{'_id': /.*CM.*/}               ||find _id where _id contains   ->CM
{'_id': /^CM/}                  ||find _id where _id starts     ->CM
{'_id': /CM$/}                  ||find _id where _id ends       ->CM

{'_id': /.*UcM075237.*/i}       ||find _id where _id contains   ->UcM075237, ignore upper/lower case
{'_id': /^UcM075237/i}          ||find _id where _id starts     ->UcM075237, ignore upper/lower case
{'_id': /UcM075237$/i}          ||find _id where _id ends       ->UcM075237, ignore upper/lower case

كنت قد واجهت مشكلة مماثلة وهذا ما عمل لي:

  const flavorExists = await Flavors.findOne({
    'flavor.name': { $regex: flavorName, $options: 'i' },
  });
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top