如何用“ like”查询MongoDB?


1437

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

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

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


7
看到MongoDB的文档:高级查询-正则表达式mongodb.org/display/DOCS/...
douyw

7
您的问题至少5like-operator标签具有投票权。我可以请您建议像sql这样同义词吗?
Kermit

3
该链接可能会对您有帮助goo.gl/gdTYK8
Dilip Kr Singh

Answers:


1945

那必须是:

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

或类似:

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

您正在寻找某处包含“ m”的东西(SQL的' %'运算符等效于Regexp的' .*'),而不是在字符串的开头锚定了“ m”的东西。

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

有关正则表达式的更多信息,请参阅此链接 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions


96
正则表达式搜索昂贵吗?
Freewind

147
实际上,这取决于。如果查询不使用索引,而必须执行表扫描,那么它肯定会很昂贵。如果您要执行“开头为”正则表达式查询,则可以使用索引。最好运行一个explain()来看看发生了什么。
凯尔·班克

35
当不锚定到字符串的开头时,它会有些昂贵。但是话又说回来,LIKESQL查询也是如此。
艾米丽2010年

4
所以只要将其锚定到字符串的开头就可以了吗?那么酷。这是否意味着我们需要添加^
user4951

44
我要添加正则表达式ijavascript db.users.find({ "name": { $regex: /m/i } })
Doron Segal 2015年

368
db.users.insert({name: 'paulo'})
db.users.insert({name: 'patric'})
db.users.insert({name: 'pedro'})

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

出:paulo,patric

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

出:paulo,patric

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

出:佩德罗


很好的例子!我发现带有空间的检查结束并发现了这一点:) / $ /
Phuong

您如何找到姓名的所有条目?还是SQL中*的通配符?会 select name from users;列出所有用户的内容吗?
anon58192932

1
@ anon58192932要在名为“ users”的表中仅显示“ name”字段的所有条目,可以通过将所需字段的值设置为1来使用project()方法。project()中未提及的字段将不会除_id以外获取。默认情况下会打印_id字段,您可以通过将_id的0值放入project()方法中来禁止显示。类似于-db.collection.find()。project({name:1,_id:0}).toArray(function(err,docs){console.log(docs); callback(docs);}); 请参阅此文档-docs.mongodb.com/manual/tutorial/…–
gauravparmar

282

  • 使用Python的PyMongo
  • 猫鼬使用Node.js
  • Jongo,使用Java
  • MGO,用围棋

你可以做:

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

2
它对区分大小写的搜索效果很好,请您告诉我如何使它执行不区分大小写的搜索?
塔希尔·亚辛

什么是正则表达式%sometext%
Tahir Yasin'Mar

64
@TahirYasin如果您仍然想知道,则不区分大小写的搜索将像这样进行:db.users.find({'name': {'$regex': 'sometext', '$options': 'i'}})
sumowrestler

我使用mgo在golang中解决了以下简单代码,选择器:= bson.M {“ technician”:bson.M {“ $ regex”:tech}}
Sandun Priyanka

1
感觉应该是公认的答案。这是目前最简单,最优雅的产品。
Brett84c

88

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

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

4
python + mongoengine:people = People.objects.raw_query({'name':{'$ regex':'m'}})
panchicore 2012年

1
如果您的RegEx值源自用户输入(例如,过滤器表单),并且您不希望将该值本身当作RegExp,则应该对其应用preg_quote()。
菲利普·里伯

2
我只是意识到了这一点,但这实际上是错误的答案,即使它工作得不是很理想,您也应该通过MongoRegex使用实际的BSON regex对象,$ regex在某些命令中具有兼容性问题,例如$ in
Sammaye

如果值存储在变量中,则此语法很有用,因此查询可以写为(在Ruby中):$collection.where(field => {"$regex" => value})
Donny Kurnia

但是,为什么不能使用数组文字呢?
Alper


53

已经有很多答案。我使用正则表达式为字符串搜索提供了不同类型的要求和解决方案。

您可以使用包含单词(例如)的正则表达式来做。您也可以使用$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'}})

保持为书签,以及您可能需要的任何其他改变的参考。


37

您有2个选择:

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

要么

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

在第二个选项中,您有更多选项,例如使用不区分大小写的选项中的“ i”。关于“字符串”,例如,可以使用“ .string。 ”(%string%)或“ string。*”(string%)和“。* string)(%string)。可以使用正则表达式如你所愿。

请享用!


34

如果使用node.js表示您可以编写以下代码:

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

另外,您可以这样编写:

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

Ruby中的类似语法:collection.where(field => Regexp.new(value))
Donny Kurnia

24

您已经得到了答案,但正则表达式与不区分大小写的匹配

您可以使用以下查询

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

i/m/i表示不区分大小写和.pretty()提供了一个更漂亮输出


但是如果我想在这里动态设置值怎么办
KS

@KuldeepKoranga,您可以将任何动态值替换为“ m”。那是你要的吗。
The6thSense

var search="feacebook"所以我该如何在@ The6thSens下面设置是的,但是db.users.find ({ "name" : /search/i } )
KS

@KuldeepKoranga您已分配值。
The6thSense

1
@KuldeepKoranga stackoverflow.com/questions/7790811/...这是否帮助
The6thSense


13

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

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

6
请注意,AFAIK Mongodb的文本搜索默认情况下仅对整个单词有效,因此它将匹配“ This is a string with text”而不是“ This is a subtext”的值。因此它不太像sql的“ LIKE”运算符。
火箭猴

@Rocketmonkeys是真的。.对于类似“ LIKE运算符”的东西,您可以使用$ regex mongo运算符。
cmarrero01

13

nodejs项目中使用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);
            });

如何使用类似查询?我已经尝试过但不起作用:searchQuery.product_name = '/'+req.query.search.value+'/i';
穆罕默德·沙阿扎德

可以尝试:searchQuery.product_name= {$regex: req.query.search.value, $options: 'i'};
Shaishab Roy

你救了我的命。您能否解释一下$ regex和$ options是什么?
穆罕默德·沙扎德

if(req.query.search.value){ searchQuery.product_name = {$regex: req.query.search.value, $options: 'i'}; searchQuery.sale_amount = {$regex: req.query.search.value, $options: 'i'}; searchQuery.sale_person = {$regex: req.query.search.value, $options: 'i'}; searchQuery.department_name = {$regex: req.query.search.value, $options: 'i'}; searchQuery.sale_date = {$regex: req.query.search.value, $options: 'i'}; }您能否看一下为什么这不起作用?
穆罕默德·沙扎德

很好地$regex: 'value' 为您的搜索值生成正则表达式,$options: 'i'意味着不区分大小写。您的代码无法正常工作,因为您对不同的属性使用了相同的值,并且该行为条件不适合您的数据库集合。
Shaishab Roy

12

对于PHP mongo一样。
我有类似的PHP mongo的问题。我发现在某些情况下,连接正则表达式参数会有所帮助,PHP mongo find字段以开头。我想我会在这里发布以为更受欢迎的话题做贡献

例如

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)

根据先前的答案和评论,与$ regex方法相比,$ text(索引)搜索将提供更好的基准解决方案。作为参考,请检查此链接stackoverflow.com/questions/10610131/…。是否有可能用PHP和mongoDB实现$ text索引方法
sankar muniyappa

12

将模板文字与变量一起使用也可以:

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


这是从ex开头开始的searchig-如果“名字”包含testlast,并且如果我按“ last”搜索,则不会给出结果。
维卡斯·乔汉

11

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

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

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



10

在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结构,该结构更易读。


10

正则表达式是昂贵的过程。

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

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

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

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

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

完美的解决方案...正则表达式很昂贵。使用包含2000万个文档的数据集,其性能差异非常明显(这是一种轻描淡写)
nivensookharan

1
实际上,这适用于整个单词,请参阅docs.mongodb.com/manual/core/index-text/#index-entries
Thomas Ebert

8

在Go和mgo驱动程序中:

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

其中result是所寻求类型的struct实例


2
请避免使用原义中的非键字段,bson:RegEx{Pattern:"m", Options:"i"}

8

使用正则表达式匹配,如下所示。“ 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);

6

像查询将如下所示

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]

6

似乎有理由同时使用javascript /regex_pattern/模式和mongo {'$regex': 'regex_pattern'}模式。请参阅:MongoBD RegEx语法限制

这不是完整的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" }

5

如果您使用的是Spring-Data Mongodb,则可以通过以下方式进行操作:

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

4

由于Mongo Shell支持正则表达式,因此这是完全可能的。

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

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

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


4

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

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

真好!有没有办法使整个文件匹配?还是让聚合框架进行后续查询来做到这一点?此刻,比赛像:{ "_id" : ObjectId("5aba5ad988385120a01b1ac2"), "fieldExists" : 4 }
Gianfranco P.

在$ project阶段只是计划您想要什么
Vokail,

4

串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


2

我找到了一个免费的工具,可以将MYSQL查询转换为MongoDB。http://www.querymongo.com/ 我检查了几个查询。正如我所见,几乎所有这些都是正确的。据此,答案是

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

2

MongoRegex已弃用。
使用MongoDB \ BSON \ Regex

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

重要的是要注意,这是指PHP中MongoRegex类。与与Node有关的这个问题不太相关。这可能应该是评论或更好的评论-在单独的帖子中回答自己的问题。
波阿斯-恢复莫妮卡

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

当我们搜索字符串模式时,总是最好使用上面的模式,因为我们不确定大小写。希望有帮助!!!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.