How do I make case-insensitive queries on Mongodb?

后端 未结 12 1108
北恋
北恋 2020-11-27 12:02
var thename = \'Andrew\';
db.collection.find({\'name\':thename});

How do I query case insensitive? I want to find result even if \"andrew\";

相关标签:
12条回答
  • 2020-11-27 12:18

    ... with mongoose on NodeJS that query:

    const countryName = req.params.country;
    
    { 'country': new RegExp(`^${countryName}$`, 'i') };
    

    or

    const countryName = req.params.country;
    
    { 'country': { $regex: new RegExp(`^${countryName}$`), $options: 'i' } };
    
    // ^australia$
    

    or

    const countryName = req.params.country;
    
    { 'country': { $regex: new RegExp(`^${countryName}$`, 'i') } };
    
    // ^turkey$
    

    A full code example in Javascript, NodeJS with Mongoose ORM on 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);
            });
    });
    
    0 讨论(0)
  • 2020-11-27 12:21
    1. With Mongoose (and Node), this worked:

      • User.find({ email: /^name@company.com$/i })

      • User.find({ email: new RegExp(`^${emailVariable}$`, 'i') })

    2. In MongoDB, this worked:

      • db.users.find({ email: { $regex: /^name@company.com$/i }})

    Both lines are case-insensitive. The email in the DB could be NaMe@CompanY.Com and both lines will still find the object in the DB.

    Likewise, we could use /^NaMe@CompanY.Com$/i and it would still find email: name@company.com in the DB.

    0 讨论(0)
  • 2020-11-27 12:25

    You can use Case Insensitive Indexes:

    The following example creates a collection with no default collation, then adds an index on the name field with a case insensitive collation. International Components for 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 } } )
    

    To use the index, queries must specify the same collation.

    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 } )
    

    or you can create a collection with default collation:

    db.createCollection("users", { collation: { locale: 'tr', strength: 2 } } )
    db.users.createIndex( { name : 1 } ) // inherits the default collation
    
    0 讨论(0)
  • 2020-11-27 12:29

    An easy way would be to use $toLower as below.

    db.users.aggregate([
        {
            $project: {
                name: { $toLower: "$name" }
            }
        },
        {
            $match: {
                name: the_name_to_search
            }
        }
    ])
    
    0 讨论(0)
  • 2020-11-27 12:30

    Chris Fulstow's solution will work (+1), however, it may not be efficient, especially if your collection is very large. Non-rooted regular expressions (those not beginning with ^, which anchors the regular expression to the start of the string), and those using the i flag for case insensitivity will not use indexes, even if they exist.

    An alternative option you might consider is to denormalize your data to store a lower-case version of the name field, for instance as name_lower. You can then query that efficiently (especially if it is indexed) for case-insensitive exact matches like:

    db.collection.find({"name_lower": thename.toLowerCase()})
    

    Or with a prefix match (a rooted regular expression) as:

    db.collection.find( {"name_lower":
        { $regex: new RegExp("^" + thename.toLowerCase(), "i") } }
    );
    

    Both of these queries will use an index on name_lower.

    0 讨论(0)
  • 2020-11-27 12:37

    I have solved it like this.

     var thename = 'Andrew';
     db.collection.find({'name': {'$regex': thename,$options:'i'}});
    

    If you want to query on 'case-insensitive exact matchcing' then you can go like this.

    var thename =  '^Andrew$';
    db.collection.find({'name': {'$regex': thename,$options:'i'}});
    
    0 讨论(0)
提交回复
热议问题