我有一个基本的用户群,他们有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) {
...
});
答案 0 :(得分:7)
我在代码中发现了一些错误,导致了不良后果。
聚合管道接受聚合框架操作数组。在您的情况下,您缺少[]
运算符。它应该像
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' } ]
。
答案 1 :(得分:1)
您不需要使用聚合框架来选择给定值所在的文档" 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 }
答案 2 :(得分:0)
聚合函数的参数必须是包含管道阶段文档的数组
var query = 'bob j';
Users.aggregate([ //pipeline array
{$project:{name: { $concat : [ "$firstName", " ", "$lastName" ] }}}, //stage1
{$match : { name: { $regex: query, $options:'i'}}} //stage2
])
答案 3 :(得分:0)
使用最新的mongodb版本 4.2 ,您可以使用$regexMatch
聚合。像这样
db.collection.find({
"$expr": {
"$regexMatch": {
"input": { "$concat": ["$firstName", " ", "$lastName"] },
"regex": "a", //Your text search here
"options": "i"
}
}
})
答案 4 :(得分:0)
此代码已经过测试,可以正常工作:
想象这个集合像这样{name :{first:'','last:''}}
查询应如下所示:db.collectionName.find({ $or : [
{ 'name.first':{ $regex: 'search', $options: '-i' } },
{ 'name.last': { $regex: 'search', $options: '-i' } },
]})
;
答案 5 :(得分:-2)
您可以使用$或(see the doc)
User.find({ $or: [
{$match: {"firstName": {$regex: "/bob j/i"}}},
{$match: {"lastName": {$regex: "/bob j/i"}}}
] });
未经测试