如何用“喜欢”查询MongoDB

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

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

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

1526689 次浏览

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

例如,

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

这应该是:

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

或者类似:

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

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

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

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

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

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

  • PyMongo使用python
  • 猫鼬使用Node.js
  • Jongo,使用Java
  • mgo,使用

你可以这样做:

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

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

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

参考:$在哪里

如果使用Node.js它说,你可以这样写:

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

,你可以这样写:

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

在Go和mgo驱动程序中:

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

其中结果是抢手类型的struct实例。

在SQL,'喜欢'查询如下所示:

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结构。

db.users.insert({name: 'patrick'})db.users.insert({name: 'petra'})db.users.insert({name: 'pedro'})

因此:

用于:

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

输出:帕特里克,佩特拉

用于:

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

输出:patrick

用于:

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

输出:pedro

您可以使用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"}});

对于PHPmongo喜欢

我在PHPmongo喜欢中遇到了几个问题。我发现连接正则表达式参数在某些情况下有帮助-PHPmongo查找字段以

例如,

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)

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

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

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

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

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

喜欢查询将如下所示:

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

对于ScalaReactiveMongo应用场景 API,

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

Node.js项目中并使用猫鼬,使用喜欢查询:

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

对于Node.js中的猫鼬

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

使用如下匹配的正则表达式。'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);

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

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

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

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

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

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

包含string

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

不包含string,仅包含正则表达式

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

不区分大小写string

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

string开始

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

string结尾

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

保留正则表达式备忘单作为书签,并作为您可能需要的任何其他更改的参考。

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

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

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

我找到了一个免费的工具来翻译mysql查询到MongoDB:http://www.querymongo.com/

我检查了几个问题。在我看来,几乎所有的问题都是正确的。根据这一点,答案是

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

似乎有理由同时使用JavaScript/regex_pattern/模式和MongoDB{'$regex': 'regex_pattern'}模式。参见:MongoDB RegEx语法限制

这不是一个完整的正则表达式教程,但我在看到高度投票的模棱两可的帖子后受到启发运行这些测试。

> ['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" }

MongoRegex已被弃用。

使用MongoDB\BSON\正则表达式

$regex = new MongoDB\BSON\Regex ( '^m');$cursor = $collection->find(array('users' => $regex));//iterate through the cursor

如果您使用的是PHP,您可以使用MongoDB_DataObject包装器,如下所示:

$model = new MongoDB_DataObject();
$model->query("select * from users where name like '%m%'");
while($model->fetch()) {var_dump($model);}

$model = new MongoDB_DataObject('users);
$model->whereAdd("name like '%m%'");
$model->find();
while($model->fetch()) {var_dump($model);}

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

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

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

你有两个选择:

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

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

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

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

FullName类似于'last',状态为=='挂起'在两个日期之间:

db.orders.find({createdAt:{$gt:ISODate("2017-04-25T10:08:16.111Z"),$lt:ISODate("2017-05-05T10:08:16.111Z")},status:"Pending",fullName:/last/}).pretty();

状态=='待处理'和orderId喜欢'PHA876174':

db.orders.find({status:"Pending",orderId:/PHA876174/}).pretty();

用途:

db.customer.find({"customerid": {"$regex": "CU_00000*", "$options": "i"}}).pretty()

当我们搜索字符串模式时,最好使用上面的模式,因为我们不确定大小写。

>> db.car.distinct('name')[ "honda", "tat", "tata", "tata3" ]
>> db.car.find({"name":/. *ta.* /})

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

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

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

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

创建一个文本索引的字段,你想使搜索:

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

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

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

将模板文字与变量一起使用也有效:

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

您还可以使用通配符过滤器,如下所示:

{"query": { "wildcard": {"lookup_field":"search_string*"}}}

请务必使用*

String Your db={Deepakparmar, dipak, parmar}#初始化数据库

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

ansDeepakparmar

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

ans迪帕克帕尔马

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

ans深度分析

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

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

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

例如,如果没有转义,则搜索字符串“A.”也将匹配“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") });

这是使用“开始”范例的命令:

db.customer.find({"customer_name" : { $regex : /^startswith/ }})

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

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

与以下结果相同:

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

有多种方法可以做到这一点。

最简单的一个:

db.users.find({"name": /m/})
{ <field>: { $regex: /pattern/, $options: '<options>' } }{ <field>: { $regex: 'pattern', $options: '<options>' } }{ <field>: { $regex: /pattern/<options> } }
db.users.find({ "name": { $regex: "m"} })

更多细节可以在$regex中找到。

找到与喜欢查询等效的结果的一种方法:

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

其中i用于不区分大小写的获取数据。

另一种方式,我们也可以得到结果:

db.collection.find({"name":/aus/})

上面将提供在包含澳大利亚的名称中具有澳大利亚的结果。

以防万一,有人正在寻找一个SQL喜欢类型的查询,用于保存字符串数组而不是字符串的键,这里是:

db.users.find({"name": {$in: [/.*m.*/]}})

前面的答案完美地回答了有关核心MongoDB查询的问题。但是当使用基于模式的搜索查询时,例如:

{"关键字":{"$regex":"^toron.*"}}

{"关键字":{"$regex":"^toron"}}

在带有@Query注释的Spring Boot JPA存储库查询中,使用如下查询:

@Query(value = "{ keyword : { $regex : ?0 }  }")List<SomeResponse> findByKeywordContainingRegex(String keyword);

调用应该是:

List<SomeResponse> someResponseList =    someRepository.findByKeywordsContainingRegex("^toron");
List<SomeResponse> someResponseList =    someRepository.findByKeywordsContainingRegex("^toron.*");

从未使用:

List<SomeResponse> someResponseList = someRepository.findByKeywordsContainingRegex("/^toron/");
List<SomeResponse> someResponseList =someRepository.findByKeywordsContainingRegex("/^toron.*/");

需要注意的重要一点:每次@陈志立语句中的?0字段都被双引号字符串替换。所以在这种情况下不应该使用正斜杠(/)!在搜索模式中始终使用双引号的模式!!例如,使用"^toron" or "^toron.*"而不是/^toron/ or /^toron.*/

使用JavaScript RegExp

  • name字符串按空格拆分并制作一个单词数组
  • 映射到迭代循环并将字符串转换为名称的每个单词的正则表达式

let name = "My Name".split(" ").map(n => new RegExp(n));console.log(name);

结果:

[/My/, /Name/]

有两种情况可以匹配字符串,

  1. #0:(类似于#1)

尝试$in表达式。要在$in查询表达式中包含正则表达式,您只能使用JavaScript正则表达式对象(即/pattern/)。例如:

db.users.find({ name: { $in: name } }); // name = [/My/, /Name/]
  1. #0:(它类似于#1条件)一个文档应该包含所有单词
db.users.find({ name: { $all: name } }); // name = [/My/, /Name/]

使用嵌套的$and$or条件和$regex

有两种情况可以匹配字符串,

  1. #0:(类似于#1)
db.users.find({$or: [{ name: { $regex: "My" } },{ name: { $regex: "Name" } }// if you have multiple fields for search then repeat same block]})

Playground

  1. #0:(类似于#1)一个文档应该包含所有单词
db.users.find({$and: [{$and: [{ name: { $regex: "My" } },{ name: { $regex: "Name" } }]}// if you have multiple fields for search then repeat same block]})

Playground

用途:

const indexSearch = await UserModel.find({ $text: { $search: filter } },);
if (indexSearch.length) {return indexSearch;}return UserModel.find({$or: [{ firstName: { $regex: `^${filter}`, $options: 'i' } },{ lastName: { $regex: `^${filter}`, $options: 'i' } },{ middleName: { $regex: `^${filter}`, $options: 'i' } },{ email: { $regex: `^${filter}`, $options: 'i' } },],},);

我使用了regex和“index”的组合。

对于Go驱动程序:

filter := bson.M{"field_name": primitive.Regex{Pattern: keyword,Options: "",},}cursor, err := GetCollection().Find(ctx, filter)

在$in查询中使用正则表达式(MongoDB留档:$in):

filter := bson.M{"field_name": bson.M{"$in": []primitive.Regex\{\{Pattern: keyword,Options: "",},}}}cursor, err := GetCollection().Find(ctx, filter)

在MongoDb中,可以使用likeMongoDb引用运算符正则表达式(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$/ })