var thename = 'Andrew';
db.collection.find({'name':thename});
ฉันจะสอบถามกรณีที่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่ได้อย่างไร ฉันต้องการค้นหาผลลัพธ์แม้ว่า "andrew";
var thename = 'Andrew';
db.collection.find({'name':thename});
ฉันจะสอบถามกรณีที่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่ได้อย่างไร ฉันต้องการค้นหาผลลัพธ์แม้ว่า "andrew";
คำตอบ:
โซลูชันของ Chris Fulstow จะใช้งานได้ (+1) อย่างไรก็ตามอาจไม่มีประสิทธิภาพโดยเฉพาะอย่างยิ่งหากคอลเล็กชันของคุณมีขนาดใหญ่มาก นิพจน์ทั่วไปที่ไม่ได้รูท (ซึ่งไม่ได้ขึ้นต้นด้วย^
ซึ่งยึดนิพจน์ทั่วไปไว้ที่จุดเริ่มต้นของสตริง) และนิพจน์ทั่วไปที่ใช้i
แฟล็กสำหรับความไม่ไวต่อตัวพิมพ์จะไม่ใช้ดัชนีแม้ว่าจะมีอยู่ก็ตาม
ตัวเลือกทางเลือกที่คุณอาจพิจารณาคือการ denormalize ข้อมูลของคุณจะเก็บเป็นรุ่นที่ต่ำกว่ากรณีของข้อมูลเช่นเป็นname
name_lower
จากนั้นคุณสามารถสืบค้นข้อมูลนั้นได้อย่างมีประสิทธิภาพ (โดยเฉพาะอย่างยิ่งหากมีการจัดทำดัชนี) สำหรับการจับคู่แบบตรงตามตัวพิมพ์เล็กและใหญ่เช่น:
db.collection.find({"name_lower": thename.toLowerCase()})
หรือด้วยการจับคู่คำนำหน้า (นิพจน์ทั่วไปที่รูท) เป็น:
db.collection.find( {"name_lower":
{ $regex: new RegExp("^" + thename.toLowerCase(), "i") } }
);
name_lower
ทั้งสองคำสั่งเหล่านี้จะใช้ดัชนีใน
new RegExp('^'+ username + '$', "i")
เพื่อให้ตรงทั้งหมด
".*"
แค่คิดที่คุณใช้รหัสนี้สำหรับหน้าเข้าสู่ระบบและชื่อผู้ใช้เป็น
คุณต้องใช้นิพจน์ทั่วไปที่ไม่คำนึงถึงขนาดตัวพิมพ์สำหรับนิพจน์นี้เช่น
db.collection.find( { "name" : { $regex : /Andrew/i } } );
ในการใช้รูปแบบ regex จากthename
ตัวแปรของคุณให้สร้างวัตถุRegExpใหม่:
var thename = "Andrew";
db.collection.find( { "name" : { $regex : new RegExp(thename, "i") } } );
UPDATE:สำหรับการแข่งขันที่แน่นอนคุณควรใช้ "name": /^Andrew$/i
regex ขอบคุณ Yannick L.
name
ไม่ใช่แค่เท่ากับ
{ "name": /^Andrew$/i }
ผมแก้แบบนี้แล้ว
var thename = 'Andrew';
db.collection.find({'name': {'$regex': thename,$options:'i'}});
หากคุณต้องการสอบถามเกี่ยวกับ 'การจับคู่แบบตรงตามตัวพิมพ์เล็กและใหญ่' คุณสามารถดำเนินการดังนี้
var thename = '^Andrew$';
db.collection.find({'name': {'$regex': thename,$options:'i'}});
ตอนนี้ MongoDB 3.4 มีความสามารถในการสร้างดัชนีที่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่ซึ่งจะเพิ่มความเร็วในการค้นหาแบบไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่บนชุดข้อมูลขนาดใหญ่ สร้างขึ้นโดยการระบุการเรียงที่มีความแข็งแรงเป็น 2
อาจเป็นวิธีที่ง่ายที่สุดคือตั้งค่าการเปรียบเทียบบนฐานข้อมูล จากนั้นคำค้นหาทั้งหมดจะสืบทอดการเรียงลำดับนั้นและจะใช้:
db.createCollection("cities", { collation: { locale: 'en_US', strength: 2 } } )
db.names.createIndex( { city: 1 } ) // inherits the default collation
คุณสามารถทำได้ดังนี้:
db.myCollection.createIndex({city: 1}, {collation: {locale: "en", strength: 2}});
และใช้มันดังนี้:
db.myCollection.find({city: "new york"}).collation({locale: "en", strength: 2});
การดำเนินการนี้จะส่งคืนเมืองที่มีชื่อว่า "new york" "New York" "New york" ฯลฯ
สำหรับข้อมูลเพิ่มเติม: https://jira.mongodb.org/browse/SERVER-90
ด้วยพังพอน (และโหนด) สิ่งนี้ได้ผล:
User.find({ email: /^name@company.com$/i })
User.find({ email: new RegExp(
`^ $ {emailVariable} $`, 'i')})
ใน MongoDB สิ่งนี้ใช้ได้:
db.users.find({ email: { $regex: /^name@company.com$/i }})
ทั้งสองบรรทัดไม่คำนึงถึงขนาดตัวพิมพ์ อีเมลในฐานข้อมูลอาจเป็นได้NaMe@CompanY.Com
และทั้งสองบรรทัดจะยังคงพบวัตถุในฐานข้อมูล
ในทำนองเดียวกันเราสามารถใช้/^NaMe@CompanY.Com$/i
และยังคงพบอีเมล: name@company.com
ในฐานข้อมูล
หากต้องการค้นหาสตริงที่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่ให้ใช้สิ่งนี้
var thename = "Andrew";
db.collection.find({"name":/^thename$/i})
ฉันเพิ่งแก้ไขปัญหานี้เมื่อไม่กี่ชั่วโมงที่ผ่านมา
var thename = 'Andrew'
db.collection.find({ $text: { $search: thename } });
คุณยังสามารถขยายได้โดยเลือกฟิลด์ที่คุณต้องการจากวัตถุผู้ใช้ของ Andrew โดยทำดังนี้
db.collection.find({ $text: { $search: thename } }).select('age height weight');
อ้างอิง: https://docs.mongodb.org/manual/reference/operator/query/text/#text
... กับพังพอนบน NodeJS ที่สอบถาม:
const countryName = req.params.country;
{ 'country': new RegExp(`^${countryName}$`, 'i') };
หรือ
const countryName = req.params.country;
{ 'country': { $regex: new RegExp(`^${countryName}$`), $options: 'i' } };
// ^australia$
หรือ
const countryName = req.params.country;
{ 'country': { $regex: new RegExp(`^${countryName}$`, 'i') } };
// ^turkey$
ตัวอย่างโค้ดแบบเต็มใน Javascript, NodeJS พร้อม Mongoose ORM บน MongoDB
// get all customers that given country name
app.get('/customers/country/:countryName', (req, res) => {
//res.send(`Got a GET request at /customer/country/${req.params.countryName}`);
const countryName = req.params.countryName;
// using Regular Expression (case intensitive and equal): ^australia$
// const query = { 'country': new RegExp(`^${countryName}$`, 'i') };
// const query = { 'country': { $regex: new RegExp(`^${countryName}$`, 'i') } };
const query = { 'country': { $regex: new RegExp(`^${countryName}$`), $options: 'i' } };
Customer.find(query).sort({ name: 'asc' })
.then(customers => {
res.json(customers);
})
.catch(error => {
// error..
res.send(error.message);
});
});
แบบสอบถามต่อไปนี้จะค้นหาเอกสารที่มีสตริงที่ต้องการโดยไม่คำนึงถึงความสำคัญและมีเหตุการณ์ร่วมด้วย
db.collection.find({name:{
$regex: new RegExp(thename, "ig")
}
},function(err, doc) {
//Your code here...
});
หากต้องการค้นหาสตริงตัวอักษรที่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่:
db.collection.find({
name: {
$regex: new RegExp('^' + name.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&') + '$', 'i')
}
});
db.collection.find({
name_lower: name.toLowerCase()
});
นิพจน์ทั่วไปช้ากว่าการจับคู่สตริงตามตัวอักษร อย่างไรก็ตามฟิลด์ตัวพิมพ์เล็กเพิ่มเติมจะเพิ่มความซับซ้อนของโค้ดของคุณ เมื่อมีข้อสงสัยให้ใช้นิพจน์ทั่วไป ฉันขอแนะนำให้ใช้เฉพาะฟิลด์ตัวพิมพ์เล็กที่ชัดเจนเท่านั้นหากสามารถแทนที่ฟิลด์ของคุณได้นั่นคือคุณไม่สนใจกรณีนี้ตั้งแต่แรก
โปรดทราบว่าคุณจะต้องออกจากชื่อก่อน regex หากคุณต้องการใช้สัญลักษณ์แทนที่ผู้ใช้ป้อนให้เลือกต่อท้าย.replace(/%/g, '.*')
หลังจากการ Escape เพื่อให้คุณสามารถจับคู่ "a%" เพื่อค้นหาชื่อทั้งหมดที่ขึ้นต้นด้วย "a"
คุณสามารถใช้Case Insensitive Indexes :
ตัวอย่างต่อไปนี้สร้างคอลเลกชันโดยไม่มีการเปรียบเทียบเริ่มต้นจากนั้นเพิ่มดัชนีในฟิลด์ชื่อด้วยการเปรียบเทียบแบบไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่ International Components สำหรับ 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
วิธีง่ายๆคือใช้ $ toLower ดังต่อไปนี้
db.users.aggregate([
{
$project: {
name: { $toLower: "$name" }
}
},
{
$match: {
name: the_name_to_search
}
}
])