如何使用 MongoDB 按名字和姓氏搜索用户?
Posted
技术标签:
【中文标题】如何使用 MongoDB 按名字和姓氏搜索用户?【英文标题】:How to search for users by both first and last name with MongoDB? 【发布时间】:2016-09-28 06:49:10 【问题描述】:我有一个基本的用户集合,其中包含他们的firstName
、lastName
和一些其他详细信息。
如何简单地通过两个名称的组合或部分搜索来搜索用户?
例如,对于一个集合:
firstName: Bob,
lastName: Jerry
,
firstName: Clark,
lastName: Mcbobby
如果搜索词是bob
,则将返回两个用户,因为第一个文档firstName
是bob,最后一个用户lastName
包含bob
。如果bob j
是搜索词,则只会返回第一个文档,因为如果两个名称组合在一起,则等于匹配搜索词的Bob Jerry
。
我尝试创建一个基本的aggregate
来连接名称,然后进行匹配,尽管 Mongoose 一直向我抛出错误:Arguments must be aggregate pipeline operators
。
这是我当前的代码:
User.aggregate(
$project: "name" : $concat : [ "$firstName", " ", "$lastName" ] ,
$match: "name": $regex: "/bob j/i"
).exec(function(err, results)
...
);
【问题讨论】:
【参考方案1】:此代码经过测试,运行良好:
想象一下集合是这样的name :first:'','last:''
查询应该是这样的:db.collectionName.find( $or : [
'name.first': $regex: 'search', $options: '-i' ,
'name.last': $regex: 'search', $options: '-i' ,
])
;
【讨论】:
【参考方案2】:使用最新的 mongodb 版本 4.2,您可以使用 $regexMatch
聚合。像这样的
db.collection.find(
"$expr":
"$regexMatch":
"input": "$concat": ["$firstName", " ", "$lastName"] ,
"regex": "a", //Your text search here
"options": "i"
)
【讨论】:
【参考方案3】:我发现您的代码中有几个错误导致了不希望的结果。
聚合管道接受聚合框架操作数组。在您的情况下,您缺少 []
运算符。应该是这样的
User.aggregate([$project...,$match...])
在 $match 阶段,您使用的是正则表达式,如果您使用的是/../
正则表达式样式,则不需要将其包裹在字符串引号中。应该是/bob j/i
这是完成的例子:
User.aggregate([
$project: "name" : $concat : [ "$firstName", " ", "$lastName" ] ,
$match: "name": $regex: /bob j/i
]).exec(function(err, result)
console.log(result);
);
您应该会在屏幕上看到[ _id: 574c3e20be214bd4078a9149, name: 'Bob Jerry' ]
。
【讨论】:
啊,好吧,因为我的聚合管道不是数组,所以抛出了错误。感谢 Saleem,您的修复工作完美无缺。【参考方案4】:您不需要使用聚合框架来选择给定值在“firstName”或“lastName”中的文档。
var reg = new RegExp(/bob/, 'i');
User.find(
'$or': [
'firstName': reg ,
'lastName': reg
]
).exec(function(err, results) // Do something
如果你想基于串联值,那么:
User.aggregate([
"$project": "name": "$concat" : [ "$firstName", " ", "$lastName" ] ,
"$match" : "name": /bob j/i
]).exec(function(err, results) // Do something
【讨论】:
【参考方案5】:聚合函数的参数必须是一个包含管道阶段文档的数组
var query = 'bob j';
Users.aggregate([ //pipeline array
$project:name: $concat : [ "$firstName", " ", "$lastName" ] , //stage1
$match : name: $regex: query, $options:'i' //stage2
])
【讨论】:
【参考方案6】:你可以使用 $or (see the doc)
User.find( $or: [
$match: "firstName": $regex: "/bob j/i",
$match: "lastName": $regex: "/bob j/i"
] );
未测试
【讨论】:
不匹配“firstName”或“lastName”吗?因此,“bob j”也不匹配,因为它是两者的组合?以上是关于如何使用 MongoDB 按名字和姓氏搜索用户?的主要内容,如果未能解决你的问题,请参考以下文章