提问人:Freewind 提问时间:7/22/2010 最后编辑:Peter MortensenFreewind 更新时间:11/11/2023 访问量:1702584
如何使用“like”查询MongoDB
How to query MongoDB with "like"
问:
我想用SQL的查询查询一些东西:like
SELECT * FROM users WHERE name LIKE '%m%'
如何在MongoDB中实现相同的目标?我在文档中找不到运算符。like
答:
您将在 MongoDB 中使用正则表达式。
例如
db.users.find({"name": /^m/})
评论
那必须是:
db.users.find({"name": /.*m.*/})
或者,类似:
db.users.find({"name": /m/})
您正在寻找某处包含“m”的东西(SQL 的 '' 运算符等同于正则表达式的 ''),而不是将“m”锚定在字符串开头的东西。%
.*
注意:MongoDB使用正则表达式(参见文档),这些表达式比SQL中的“LIKE”更强大。使用正则表达式,您可以创建您想象的任何模式。
有关正则表达式的更多信息,请参阅正则表达式 (MDN)。
评论
LIKE
javascript db.users.find({ "name": { $regex: /m/i } })
users.find({"name": new RegExp('.*' + searchVariable + '.*')})
在 PHP 中,您可以使用以下代码:
$collection->find(array('name'=> array('$regex' => 'm'));
评论
$collection->find(array('name'=> array('$regex' => 'm', '$options => 'i'));
在
- 使用 Python 的 PyMongo
- 使用 Node.js 的猫鼬
- Jongo,使用 Java
- mgo, 使用 Go
您可以执行以下操作:
db.users.find({'name': {'$regex': 'sometext'}})
评论
db.users.find({'name': {'$regex': 'sometext', '$options': 'i'}})
您可以使用 where 语句来构建任何 JavaScript 脚本:
db.myCollection.find( { $where: "this.name.toLowerCase().indexOf('m') >= 0" } );
参考: $where
评论
$where
效率非常低下。:(进行全集合扫描
如果使用 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') } );
评论
在 Go 和 mgo 驱动程序中:
Collection.Find(bson.M{"name": bson.RegEx{"m", ""}}).All(&result)
其中 result 是 sought-after 类型的 struct 实例。
评论
bson:RegEx{Pattern:"m", Options:"i"}
在 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
此外,该方法将在所有位置生成更具可读性的格式化 JSON 结构。pretty()
db.users.insert({name: 'patrick'})
db.users.insert({name: 'petra'})
db.users.insert({name: 'pedro'})
因此:
为:
db.users.find({name: /a/}) // Like '%a%'
输出: patrick, petra
为:
db.users.find({name: /^pa/}) // Like 'pa%'
输出:patrick
为:
db.users.find({name: /ro$/}) // Like '%ro'
输出: pedro
评论
db.users.find({name: /^path\/to\/something/}) // Like 'path/to/something%'
您可以使用 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"
}
});
评论
对于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)
您已经得到了答案,但要与不区分大小写的正则表达式匹配,可以使用以下查询:
db.users.find ({ "name" : /m/i } ).pretty()
in 表示不区分大小写,并提供更漂亮的输出。i
/m/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);
对于 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]
在 Node.js 项目中并使用 Mongoose,使用类似的查询:
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});
以下是使用正则表达式进行字符串搜索的不同类型的要求和解决方案。
您可以使用包含单词的正则表达式,即 like。此外,您还可以用于不区分大小写的搜索。$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模式和MongoDB模式。请参见: MongoDB RegEx 语法限制/regex_pattern/
{'$regex': 'regex_pattern'}
这不是一个完整的正则表达式教程,但在看到上面一篇投票率很高的模棱两可的帖子后,我受到启发运行这些测试。
> ['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:
$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)”,例如。您可以根据需要使用正则表达式。
全名,如“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();
status== 'Pending' 和 orderId LIKE '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*"}}}
请务必使用 .*
字符串 yourdb={deepakparmar, dipak, parmar}
db.getCollection('yourdb').find({"name":/^dee/})
Ans迪帕克帕尔马
db.getCollection('yourdb').find({"name":/d/})
Ans Deepakparmar, 迪帕克
db.getCollection('yourdb').find({"name":/mar$/})
Ans Deepakparmar, 帕尔马
您可以使用正则表达式进行查询:
db.users.find({"name": /m/});
如果字符串来自用户,您可能希望在使用字符串之前对字符串进行转义。这将防止用户的文字字符被解释为正则表达式标记。
例如,搜索字符串“A”。也会匹配“AB”,如果没有转义。
在使用字符串之前,您可以使用 simple 来转义字符串。我把它做成一个重用的函数: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; //John
db.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/})
以上将提供在包含 aus 的名称中包含 aus 的结果。
以防万一,有人正在寻找一种类似 SQL 的查询来查询包含字符串数组而不是字符串的键,这里是:
db.users.find({"name": {$in: [/.*m.*/]}})
前面的答案完美地回答了有关核心MongoDB查询的问题。但是,当使用基于模式的搜索查询时,例如:
{“keywords”:{ “$regex”: “^toron.*”}}
或
{“keywords”:{ “$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 字段替换为双引号字符串@Query。因此,在这些情况下不应使用正斜杠 (/)!在搜索模式中始终使用双引号来寻找模式!!例如,使用"^toron" or "^toron.*"
/^toron/ or /^toron.*/
评论
使用 JavaScript 正则表达式
- 按空格拆分字符串并组成一个单词数组
name
- 映射到迭代循环,并将字符串转换为名称中每个单词的正则表达式
let name = "My Name".split(" ").map(n => new RegExp(n));
console.log(name);
结果:
[/My/, /Name/]
有两种方案可以匹配字符串,
$in
:(类似于$or
条件)
尝试$in表达式。若要在查询表达式中包含正则表达式,只能使用 JavaScript 正则表达式对象(即 )。例如:$in
/pattern/
db.users.find({ name: { $in: name } }); // name = [/My/, /Name/]
$all
:(类似于$and
条件)文档应包含所有单词
db.users.find({ name: { $all: name } }); // name = [/My/, /Name/]
使用嵌套和条件,以及$and
$or
$regex
有两种方案可以匹配字符串,
$or
:(类似于$in
条件)
db.users.find({
$or: [
{ name: { $regex: "My" } },
{ name: { $regex: "Name" } }
// if you have multiple fields for search then repeat same block
]
})
$and
:(类似于$all
条件)文档应包含所有单词
db.users.find({
$and: [
{
$and: [
{ name: { $regex: "My" } },
{ name: { $regex: "Name" } }
]
}
// if you have multiple fields for search then repeat same block
]
})
用:
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' } },
],
},
);
我使用了正则表达式和“索引”的组合。
对于 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中,可以使用像使用MongoDb引用运算符正则表达式(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$/ })
评论
如果你想使用像 mongo JPA 这样的查询,你应该试试这个。
@Query("{ 'title' : { $regex: '^?0', $options: 'i' } }")
List<TestDocument> findLikeTitle(String title);
它也有效:
db.getCollection('collection_name').find({"field_name": /^searched_value/})
下一个:将存储过程的结果插入到临时表中
评论
$text
$regex