如何使用 MongoDB 按名字和姓氏搜索用户?

Posted

技术标签:

【中文标题】如何使用 MongoDB 按名字和姓氏搜索用户?【英文标题】:How to search for users by both first and last name with MongoDB? 【发布时间】:2016-09-28 06:49:10 【问题描述】:

我有一个基本的用户集合,其中包含他们的firstNamelastName 和一些其他详细信息。

如何简单地通过两个名称的组合或部分搜索来搜索用户?

例如,对于一个集合:


   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 按名字和姓氏搜索用户?的主要内容,如果未能解决你的问题,请参考以下文章

如何在搜索栏中按名字和姓氏排序 - Sqlite

按名字和姓氏自动完成搜索

mongoDB中的名字和姓氏组合搜索

mongoDB中的名字和姓氏组合搜索

在 MongoDB 中搜索多个集合

多个类似子句 Codeigniter