如何在MongoDB中使用类似SQL的LIKE查询

如何在MongoDB中使用类似SQL的LIKE查询

技术背景

在关系型数据库(如SQL)中,我们经常使用 LIKE 操作符进行模糊查询。而在MongoDB中,没有直接的 LIKE 操作符,但可以使用正则表达式来实现类似的功能。MongoDB的正则表达式功能比SQL的 LIKE 更强大,能够创建更复杂的匹配模式。

实现步骤

1. 使用正则表达式进行查询

在MongoDB中,可以使用正则表达式进行模糊查询。以下是一些常见的查询示例:

  • 包含特定字符串
1
db.users.find({"name": /m/})
  • 不区分大小写的包含查询
1
db.collection.find({name: {'$regex': 'string', '$options': 'i'}})
  • 不包含特定字符串
1
db.collection.find({name: {'$regex': '^((?!string).)*$', '$options': 'i'}})
  • 精确的不区分大小写匹配
1
db.collection.find({name: {'$regex': '^string$', '$options': 'i'}})
  • 以特定字符串开头
1
db.collection.find({name: {'$regex': '^string', '$options': 'i'}})
  • 以特定字符串结尾
1
db.collection.find({name: {'$regex': 'string$', '$options': 'i'}})

2. 在不同编程语言和框架中使用

  • Python + PyMongo
1
2
3
4
5
6
7
8
9
10
from pymongo import MongoClient

client = MongoClient()
db = client.test_database
collection = db.users

query = {'name': {'$regex': 'sometext'}}
result = collection.find(query)
for doc in result:
print(doc)
  • Node.js + Mongoose
1
2
3
4
5
6
7
8
9
10
11
12
13
const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/test', { useNewUrlParser: true, useUnifiedTopology: true });

const User = mongoose.model('User', { name: String });

const searchQuery = { name: { $regex: 'sometext', $options: 'i' } };
User.find(searchQuery, (error, users) => {
if (error) {
console.error(error);
} else {
console.log(users);
}
});
  • Java + Jongo
1
2
3
4
5
6
7
8
9
10
11
12
import org.jongo.Jongo;
import org.jongo.MongoCollection;
import com.mongodb.MongoClient;

MongoClient mongoClient = new MongoClient("localhost", 27017);
Jongo jongo = new Jongo(mongoClient.getDB("test"));
MongoCollection users = jongo.getCollection("users");

Iterable<org.jongo.ResultHandler<org.bson.Document>> results = users.find("{name: {$regex: 'sometext'}}").as(org.bson.Document.class);
for (org.bson.Document doc : results) {
System.out.println(doc);
}
  • Go + mgo
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package main

import (
"gopkg.in/mgo.v2"
"gopkg.in/mgo.v2/bson"
"fmt"
)

func main() {
session, err := mgo.Dial("localhost:27017")
if err != nil {
panic(err)
}
defer session.Close()

c := session.DB("test").C("users")
var result []interface{}
err = c.Find(bson.M{"name": bson.RegEx{"m", ""}}).All(&result)
if err != nil {
panic(err)
}
fmt.Println(result)
}

3. 使用聚合管道进行子字符串搜索

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
db.collection.aggregate([
{
$project: {
fieldExists: {
$indexOfBytes: ['$field', 'string']
}
}
},
{
$match: {
fieldExists: {
$gt: -1
}
}
},
{
$limit: 5
}
]);

核心代码

简单的正则表达式查询

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

不区分大小写的正则表达式查询

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

使用JavaScript函数进行字符串转正则表达式

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

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

最佳实践

  • 使用索引:正则表达式查询可能会比较慢,尤其是在处理大量数据时。可以为需要查询的字段创建文本索引,然后使用 $text$search 进行搜索。
1
2
3
4
db.collection.createIndex({name: 'text', otherField: 'text'});
db.collection.find({
'$text': {'$search': "The string"}
})
  • 转义用户输入:如果查询字符串来自用户输入,需要对其进行转义,以防止特殊字符被解释为正则表达式的元字符。

常见问题

  • 正则表达式性能问题:正则表达式查询可能会消耗大量的CPU资源,尤其是在处理大量数据时。可以通过创建索引或使用聚合管道来优化查询性能。
  • 大小写问题:默认情况下,正则表达式查询是区分大小写的。可以使用 $options: 'i' 来进行不区分大小写的查询。
  • MongoRegex 已弃用:在PHP中,MongoRegex 已被弃用,应使用 MongoDB\BSON\Regex 代替。
1
2
$regex = new MongoDB\BSON\Regex ('^m');
$cursor = $collection->find(array('users' => $regex));

如何在MongoDB中使用类似SQL的LIKE查询
https://119291.xyz/posts/how-to-query-mongodb-with-like/
作者
ww
发布于
2025年5月23日
许可协议