我知道可以通过以下方式检查字段值是否类似于字符串:
db.users.findOne({"username" : {$regex : ".*jo*"}});
但我想要的是检查一个字符串是否包含字段值。
如果我有这样一个字符串:"John, Smith,"
,我想匹配用户名为"John"
和"Smith"
的用户。
我知道可以拆分字符串并使用$in
运算符,但想知道是否可以通过字符串比较轻松地完成。
我知道可以通过以下方式检查字段值是否类似于字符串:
db.users.findOne({"username" : {$regex : ".*jo*"}});
但我想要的是检查一个字符串是否包含字段值。
如果我有这样一个字符串:"John, Smith,"
,我想匹配用户名为"John"
和"Smith"
的用户。
我知道可以拆分字符串并使用$in
运算符,但想知道是否可以通过字符串比较轻松地完成。
$regex
是您需要的。/* 1 */
{
"_id" : ObjectId("5a8498a29d1ed018c7f648ca"),
"name" : "John, Smith, "
}
查找和$regex
看起来像:
db.foo.find({ name: { $regex: 'John.*Smith' } }, { _id : 0 })
db.foo.find({ name: { $regex: 'john.*smith', $options: 'i'} }, { _id : 0 })
输出:
/* 1 */
{
"name" : "John, Smith, "
}
db.foo.find( { name: { $regex: 'Bill.*Smith', $options: 'i' }}, { _id : 0})
或者
db.foo.find( { name: { $regex: 'John.*Bill', $options: 'i' } }, { _id : 0})
输出:
Fetched 0 record(s) in 1ms
因此,$regex
只有在字段中同时出现 John
和 Smith
时才会返回匹配项。
具体来说,关于 $regex
本身:
.
匹配除换行符以外的任何单个字符
*
匹配前面的表达式0次或多次
$option
i
用于大小写不敏感
从Mongodb 3.4开始,他们引入了$indexOfCP
操作符。
在字符串中搜索子字符串并返回第一个出现的UTF-8代码点索引(从零开始)。如果未找到子字符串,则返回-1。
因此,以下内容有效:
db.user.aggregate(
[
{
$addFields:
{
searchIndex: { $indexOfCP: [ "$username", "John, Smith, " ] },
}
},
{
$match: {
searchIndex: {$ne: -1}
}
},
]
)
这将匹配用户名类似于:"Jo"、"John"、"Smit"、"Smith"等用户。
$indexOfCP
数组中的元素顺序不是倒置的吗?超级字符串 应该是第一个元素,子字符串 应该是第二个元素。 - May Rest in Peace除了接受的答案外,从 v3.6 开始,可以通过 $expr
直接在 find()
中使用 $indexOfCP
db.foo.find({
"$expr": {
{$ne : [{$indexOfCP: ["John, Smith, ", "$username"]}, -1]}
}
})
{ "_id" : ObjectId("5a8498a29d1ed018c7f648ca"), "name" : "John, Smith, " }
并且您的搜索字符串是JohnSmithBobAlexAlice
,那么您的查询是否匹配? - dsharew