ChatGPT解决这个技术问题 Extra ChatGPT

如何使用“like”查询 MongoDB

我想用 SQL 的 like 查询来查询一些东西:

SELECT * FROM users  WHERE name LIKE '%m%'

如何在 MongoDB 中实现相同的目标?我在 the documentation 中找不到 like 的运算符。

请参阅 mongodb 的文档:高级查询 -- 正则表达式 mongodb.org/display/DOCS/…
我强烈建议您看看 MongoDB Atlas Search,因为它对于 $text$regex 的“类似”查询来说资源效率更高且功能丰富

P
Peter Mortensen

那必须是:

db.users.find({"name": /.*m.*/})

或者,类似的:

db.users.find({"name": /m/})

您正在寻找某处包含“m”的内容(SQL 的“%”运算符等效于正则表达式““.*”),而不是“m”锚定在字符串开头的内容。

注意:MongoDB 使用的正则表达式比 SQL 中的“LIKE”更强大。使用正则表达式,您可以创建您想象的任何模式。

有关正则表达式的更多信息,请参阅 Regular expressions (MDN)。


通过正则表达式搜索昂贵吗?
实际上,这取决于。如果查询不使用索引,并且必须进行表扫描,那么它肯定会很昂贵。如果您正在执行“开始于”正则表达式查询,那么可以使用索引。最好运行一个 explain() 来查看发生了什么。
当不锚定到字符串的开头时,它有点昂贵。但话又说回来,SQL 中的 LIKE 查询也是如此。
我会添加正则表达式 i javascript db.users.find({ "name": { $regex: /m/i } })
值得一提的是,如果您想从 Node 应用程序中使用它并且想要动态搜索,您可以使用:users.find({"name": new RegExp('.*' + searchVariable + '.*')}) 因此,您可以将它与 $in、$nin 等其他运算符一起使用。
M
Manuel Jordan
db.users.insert({name: 'paulo'})
db.users.insert({name: 'patric'})
db.users.insert({name: 'pedro'})

所以:

为了:

db.users.find({name: /a/})  // Like '%a%'

输出:保罗,帕特里克

为了:

db.users.find({name: /^pa/}) // Like 'pa%'

输出:保罗,帕特里克

为了:

db.users.find({name: /ro$/}) //like '%ro'

输出:佩德罗


你知道为什么你有这么多的赞成票吗?因为文档应该得到同样多的反对票!谢谢
K
Kirill Husiatyn

PyMongo 使用 Python

使用 Node.js 的猫鼬

Jongo,使用 Java

mgo,使用 Go

你可以做:

db.users.find({'name': {'$regex': 'sometext'}})

@TahirYasin 如果您仍然想知道,不区分大小写的搜索将像这样完成:db.users.find({'name': {'$regex': 'sometext', '$options': 'i'}})
这适用于整个单词,而不是单词的一部分。
P
Peter Mortensen

在 PHP 中,您可以使用以下代码:

$collection->find(array('name'=> array('$regex' => 'm'));

P
Peter Mortensen

以下是使用正则表达式进行字符串搜索的不同类型的要求和解决方案。

您可以使用包含单词的正则表达式,即like。您也可以使用 $options => i 进行不区分大小写的搜索。

包含字符串

db.collection.find({name:{'$regex' : 'string', '$options' : 'i'}})

不包含字符串,只包含正则表达式

db.collection.find({name:{'$regex' : '^((?!string).)*$', '$options' : 'i'}})

不区分大小写的字符串

db.collection.find({name:{'$regex' : '^string$', '$options' : 'i'}})

以字符串开头

db.collection.find({name:{'$regex' : '^string', '$options' : 'i'}})

以字符串结尾

db.collection.find({name:{'$regex' : 'string$', '$options' : 'i'}})

Regular Expressions Cheat Sheet 保留为书签,并作为您可能需要的任何其他更改的参考。


这是稍后的评论,但是,如何在上面的示例中使用变量?比如 let name = 'john doe' 。如何在正则表达式中实现名称变量?谢谢
P
Peter Mortensen

您将在 MongoDB 中使用正则表达式。

例如,

db.users.find({"name": /^m/})

我认为这仅显示名称值以“m”开头的文档
使用正则表达式时删除引号很重要,即不要执行“/^m/”,只需执行/^m/
P
Peter Mortensen

你有两个选择:

db.users.find({"name": /string/})

或者

db.users.find({"name": {"$regex": "string", "$options": "i"}})

对于第二个,您有更多选项,例如选项中的“i”,以使用不区分大小写的方式查找。

而关于“字符串”,您可以使用“.string”。 (%string%) 或 "string.*" (string%) 和 ".*string) (%string) 例如。您可以根据需要使用正则表达式。


P
Peter Mortensen

如果使用 Node.jsit says 可以这样写:

db.collection.find( { field: /acme.*corp/i } );

// Or
db.collection.find( { field: { $regex: 'acme.*corp', $options: 'i' } } );

Also,您可以这样写:

db.collection.find( { field: new RegExp('acme.*corp', 'i') } );

谢谢@Eddy。使用正则表达式提供 '$options: 'i'' 使重构过程对我来说很容易。
P
Peter Mortensen

您已经得到了答案,但要匹配不区分大小写的正则表达式,您可以使用以下查询:

db.users.find ({ "name" : /m/i } ).pretty()

/m/i 中的 i 表示不区分大小写,.pretty() 提供更漂亮的输出。


P
Peter Mortensen

对于 Node.js 中的 Mongoose

db.users.find({'name': {'$regex': '.*sometext.*'}})

d
damd

使用 MongoDB Compass,您需要使用严格模式语法,例如:

{ "text": { "$regex": "^Foo.*", "$options": "i" } }

(在 MongoDB Compass 中,使用 " 而不是 ' 很重要)


P
Peter Mortensen

您可以使用 MongoDB 2.6 的新功能:

db.foo.insert({desc: "This is a string with text"});
db.foo.insert({desc:"This is a another string with Text"});
db.foo.ensureIndex({"desc":"text"});
db.foo.find({
    $text:{
        $search:"text"
    }
});

请注意,AFAIK Mongodb 的文本搜索默认情况下仅适用于整个单词,因此这将匹配“这是一个带有文本的字符串”之类的值,而不是“这是一个带有潜文本的字符串”。所以它不太像 sql 的“LIKE”运算符。
P
Peter Mortensen

Node.js 项目中并使用 Mongoose,使用 like 查询:

var User = mongoose.model('User');

var searchQuery = {};
searchQuery.email = req.query.email;
searchQuery.name = {$regex: req.query.name, $options: 'i'};
User.find(searchQuery, function(error, user) {
                if(error || user === null) {
                    return res.status(500).send(error);
                }
                return res.status(200).send(user);
            });

P
Peter Mortensen

您可以使用 where 语句来构建任何 JavaScript 脚本:

db.myCollection.find( { $where: "this.name.toLowerCase().indexOf('m') >= 0" } );

参考:$where


$where 效率极低。做完整的收藏扫描:(
b
besthost

使用带有变量的模板文字也可以:

{"firstname": {$regex : `^${req.body.firstname}.*` , $options: 'si' }}


P
Peter Mortensen

在 Go 和 mgo 驱动程序中:

Collection.Find(bson.M{"name": bson.RegEx{"m", ""}}).All(&result)

结果是广受欢迎的类型的结构实例。


请避免在文字中使用无键字段,改为使用 bson:RegEx{Pattern:"m", Options:"i"}
P
Peter Mortensen

对于 PHP mongo 之类的。

PHP mongo like 有几个问题。我发现连接正则表达式参数在某些情况下会有所帮助 - PHP mongo find field starts with

例如,

db()->users->insert(['name' => 'john']);
db()->users->insert(['name' => 'joe']);
db()->users->insert(['name' => 'jason']);

// starts with
$like_var = 'jo';
$prefix = '/^';
$suffix = '/';
$name = $prefix . $like_var . $suffix;
db()->users->find(['name' => array('$regex'=>new MongoRegex($name))]);
output: (joe, john)

// contains
$like_var = 'j';
$prefix = '/';
$suffix = '/';
$name = $prefix . $like_var . $suffix;
db()->users->find(['name' => array('$regex'=>new MongoRegex($name))]);

output: (joe, john, jason)

P
Peter Mortensen

在 SQL 中,“like”查询如下所示:

select * from users where name like '%m%'

在 MongoDB 控制台中,它看起来像这样:

db.users.find({"name": /m/})     // Not JSON formatted

db.users.find({"name": /m/}).pretty()  // JSON formatted

此外,pretty() 方法将在所有地方生成一个格式化的 JSON 结构,这样更易读。


D
Deepak parmar

字符串 yourdb={deepakparmar, dipak, parmar}

db.getCollection('yourdb').find({"name":/^dee/})

ans deepakparmar

db.getCollection('yourdb').find({"name":/d/})

ans deepakparmar, 迪帕克

db.getCollection('yourdb').find({"name":/mar$/})

ans deepakparmar, 帕尔马


P
Peter Mortensen

正则表达式的处理成本很高。

另一种方法是创建文本索引,然后使用 $search 进行搜索。

创建要使其可搜索的字段的文本索引:

db.collection.createIndex({name: 'text', otherField: 'text'});

在文本索引中搜索字符串:

db.collection.find({
  '$text'=>{'$search': "The string"}
})

这不适用于局部。
S
Sahil Thummar

在 MongoDb 中,可以像使用 MongoDb reference operator regular expression(regex) 一样使用。

对于相同的前。

MySQL - SELECT * FROM users  WHERE name LIKE '%m%'

MongoDb

    1) db.users.find({ "name": { "$regex": "m", "$options": "i" } })

    2) db.users.find({ "name": { $regex: new RegExp("m", 'i') } })

    3) db.users.find({ "name": { $regex:/m/i } })

    4) db.users.find({ "name": /mail/ })

    5) db.users.find({ "name": /.*m.*/ })

MySQL - SELECT * FROM users  WHERE name LIKE 'm%'

MongoDb Any of Above with /^String/

    6) db.users.find({ "name": /^m/ })

MySQL - SELECT * FROM users  WHERE name LIKE '%m'

MongoDb Any of Above with /String$/

    7) db.users.find({ "name": /m$/ })

仅供参考,在大型数据集上它变得非常慢。而且没有办法知道分数是多少。
A
Abhijit Bashetti

使用正则表达式匹配如下。 'i' 表示不区分大小写。

var collections = mongoDatabase.GetCollection("Abcd");

var queryA = Query.And(
         Query.Matches("strName", new BsonRegularExpression("ABCD", "i")), 
         Query.Matches("strVal", new BsonRegularExpression("4121", "i")));

var queryB = Query.Or(
       Query.Matches("strName", new BsonRegularExpression("ABCD","i")),
       Query.Matches("strVal", new BsonRegularExpression("33156", "i")));

var getA = collections.Find(queryA);
var getB = collections.Find(queryB);

P
Peter Mortensen

似乎有理由同时使用 JavaScript /regex_pattern/ 模式和 MongoDB {'$regex': 'regex_pattern'} 模式。请参阅:MongoDB RegEx Syntax Restrictions

这不是一个完整的正则表达式教程,但我在看到 highly voted ambiguous post above 后受到启发,开始运行这些测试。

> ['abbbb','bbabb','bbbba'].forEach(function(v){db.test_collection.insert({val: v})})

> db.test_collection.find({val: /a/})
{ "val" : "abbbb" }
{ "val" : "bbabb" }
{ "val" : "bbbba" }

> db.test_collection.find({val: /.*a.*/})
{ "val" : "abbbb" }
{ "val" : "bbabb" }
{ "val" : "bbbba" }

> db.test_collection.find({val: /.+a.+/})
{ "val" : "bbabb" }

> db.test_collection.find({val: /^a/})
{ "val" : "abbbb" }

> db.test_collection.find({val: /a$/})
{ "val" : "bbbba" }

> db.test_collection.find({val: {'$regex': 'a$'}})
{ "val" : "bbbba" }

P
Peter Mortensen

类似的查询如下所示:

db.movies.find({title: /.*Twelve Monkeys.*/}).sort({regularizedCorRelation : 1}).limit(10);

对于 Scala ReactiveMongo API,

val query = BSONDocument("title" -> BSONRegex(".*" + name + ".*", "")) // like
val sortQ = BSONDocument("regularizedCorRelation" -> BSONInteger(1))
val cursor = collection.find(query).sort(sortQ).options(QueryOpts().batchSize(10)).cursor[BSONDocument]

P
Peter Mortensen

如果你使用的是 Spring-Data MongoDB,你可以这样做:

String tagName = "m";
Query query = new Query();
query.limit(10);
query.addCriteria(Criteria.where("tagName").regex(tagName));

P
Peter Mortensen

如果您有一个字符串变量,则必须将其转换为正则表达式,因此 MongoDB 将对其使用 like 语句。

const name = req.query.title; //John
db.users.find({ "name": new Regex(name) });

与以下结果相同:

db.users.find({"name": /John/})

k
kz_sergey

使用聚合子字符串搜索(带索引!!!):

db.collection.aggregate([{
        $project : {
            fieldExists : {
                $indexOfBytes : ['$field', 'string']
            }
        }
    }, {
        $match : {
            fieldExists : {
                $gt : -1
            }
        }
    }, {
        $limit : 5
    }
]);

这可能仍然比所有这些正则表达式建议更好 - 但它仍然会进行 colscan。
E
Ezequias Dinella

您可以使用正则表达式进行查询:

db.users.find({"name": /m/});

如果字符串来自用户,也许你想在使用它之前转义字符串。这将防止来自用户的文字字符被解释为正则表达式标记。

例如,搜索字符串“A”。 will also match "AB" 如果没有转义。在使用它之前,您可以使用一个简单的 replace 来转义您的字符串。我把它作为重用的功能:

function textLike(str) {
  var escaped = str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&');
  return new RegExp(escaped, 'i');
}

所以现在,字符串变成了不区分大小写的模式,也匹配文字点。例子:

>  textLike('A.');
<  /A\./i

现在我们准备好随时生成正则表达式:

db.users.find({ "name": textLike("m") });

P
Peter Mortensen

由于 MongoDB shell 支持正则表达式,这是完全可能的。

db.users.findOne({"name" : /.*sometext.*/});

如果我们希望查询不区分大小写,我们可以使用“i”选项,如下所示:

db.users.findOne({"name" : /.*sometext.*/i});

P
Peter Mortensen

如果您想在 MongoDB 中进行“喜欢”搜索,那么您应该使用 $regex。通过使用它,查询将是:

db.product.find({name:{$regex:/m/i}})

有关更多信息,您还可以阅读文档 - $regex