MongoDB: Is it possible to make a case-insensitive query?

后端 未结 24 1800
谎友^
谎友^ 2020-11-22 04:44

Example:

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

> db.stuff.find({\"foo\":\"bar\"}).count();
1
> db.stuff.find({\"foo\":\"BAR\"}).count();
0

相关标签:
24条回答
  • 2020-11-22 05:27

    The best method is in your language of choice, when creating a model wrapper for your objects, have your save() method iterate through a set of fields that you will be searching on that are also indexed; those set of fields should have lowercase counterparts that are then used for searching.

    Every time the object is saved again, the lowercase properties are then checked and updated with any changes to the main properties. This will make it so you can search efficiently, but hide the extra work needed to update the lc fields each time.

    The lower case fields could be a key:value object store or just the field name with a prefixed lc_. I use the second one to simplify querying (deep object querying can be confusing at times).

    Note: you want to index the lc_ fields, not the main fields they are based off of.

    0 讨论(0)
  • 2020-11-22 05:30

    As you can see in mongo docs - since version 3.2 $text index is case-insensitive by default: https://docs.mongodb.com/manual/core/index-text/#text-index-case-insensitivity

    Create a text index and use $text operator in your query.

    0 讨论(0)
  • 2020-11-22 05:33

    Suppose you want to search "column" in "Table" and you want case insenstive search. The best and efficient way is as below;

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

    Above code just adds your search value as RegEx and searches in with insensitve criteria set with "i" as option.

    All the best.

    0 讨论(0)
  • 2020-11-22 05:33

    For searching a variable and escaping it:

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

    Escaping the variable protects the query against attacks with '.*' or other regex.

    escape-string-regexp

    0 讨论(0)
  • 2020-11-22 05:33

    These have been tested for string searches

    {'_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
    
    0 讨论(0)
  • 2020-11-22 05:35

    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)
提交回复
热议问题