【问题标题】:Search first, last name and email by one key word in Mongoose在 Mongoose 中通过一个关键字搜索名字、姓氏和电子邮件
【发布时间】:2017-03-15 17:58:50
【问题描述】:

您可以在下面找到我的代码,我尝试在 Mongoose 中通过一个关键字搜索字段(名字、姓氏和电子邮件)。不幸的是,它没有像我预期的那样工作。如果输入完整的名字或姓氏,它只会返回结果,但我想在所有情况下都得到结果:

例子:

用户名和姓 = John Smith

  1. 案例:keyWord = Jo
  2. 案例:keyWord = John
  3. 案例:keyWord = John Sm
  4. 案例:keyWord = John Smith
  5. 案例:keyWord = john.smith@mail.com

在名字、姓氏和电子邮件上使用文本索引的代码:

User.findOne({ _id: req.user.id })
      .populate({
        path: 'friends',
        select: 'firstName lastName email avatarPath facebookID',
        match: { $text: { $search: req.query.keyWord } }
      })
      .populate({
        path: 'receivedFriendRequests',
        select: 'firstName lastName email avatarPath facebookID',
        match: { $text: { $search: req.query.keyWord } }
      })
      .exec(function (err, user) {
        if (err) {
          logger.error('Friend 500 ' + err)
          return res.status(500).json({
            code: config.errorCode.status500.code,
            message: config.errorCode.status500.message
          })
        }
        if (!user) {
          logger.error('Friend 404 User does not exist.')
          return res.status(404).json({
            code: config.errorCode.status404.code,
            message: config.errorCode.status404.message
          })
        }else {
          if (!user.friends) {
            logger.error('Friend 404 User friends do not exist.')
            return res.status(404).json({
              code: config.errorCode.status404.code,
              message: config.errorCode.status404.message
            })
          }
          return res.json({
            receivedFriendRequests: user.receivedFriendRequests.slice(0, 5),
            data: user.friends
          })
        }
      })

我也尝试过这种方式,但它并不适用于所有 5 种情况:

User.findOne({ _id: req.user.id })
      .populate({
        path: 'friends',
        select: 'firstName lastName email avatarPath facebookID',
        match: {
          $or: [
            {
              firstName: { $regex: req.query.keyWord, $options: 'i'}
            },
            {
              lastName: { $regex: req.query.keyWord, $options: 'i'}
            },
            {
              email: { $regex: req.query.keyWord, $options: 'i'}
            }
          ]
        }
      })
      .populate({
        path: 'receivedFriendRequests',
        select: 'firstName lastName email avatarPath facebookID',
        match: {
          $or: [
            {
              firstName: { $regex: req.query.keyWord, $options: 'i'}
            },
            {
              lastName: { $regex: req.query.keyWord, $options: 'i'}
            },
            {
              email: { $regex: req.query.keyWord, $options: 'i'}
            }
          ]
        }
      })
      .exec(function (err, user) {
        if (err) {
          logger.error('Friend 500 ' + err)
          return res.status(500).json({
            code: config.errorCode.status500.code,
            message: config.errorCode.status500.message
          })
        }
        if (!user) {
          logger.error('Friend 404 User does not exist.')
          return res.status(404).json({
            code: config.errorCode.status404.code,
            message: config.errorCode.status404.message
          })
        }else {
          if (!user.friends) {
            logger.error('Friend 404 User friends do not exist.')
            return res.status(404).json({
              code: config.errorCode.status404.code,
              message: config.errorCode.status404.message
            })
          }
          return res.json({
            receivedFriendRequests: user.receivedFriendRequests.slice(0, 5),
            data: user.friends
          })
        }
      })

用户架构:

var UserSchema = new Schema({
  firstName: {
    type: String
  },
  frstNameNormalized: {
    type: String
  },
  lastName: {
    type: String
  },
  lastNameNormalized: {
    type: String
  },
  email: {
    type: String,
    // unique: true,
    // required: true,
    lowercase: true,
  // match: [/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$/, 'Please enter a valid email address']
  },
  birthDate: {
    type: Date
  },
  facebookID: {
    type: String
  },
  twitterID: {
    type: String
  },
  password: {
    type: String
  },
  nickname: {
    type: String,
    default: ''
  },
  description: {
    type: String,
    default: ''
  },
  avatarPath: {
    type: String,
    default: ''
  },
  friends: [{ type: Schema.Types.ObjectId, ref: 'User' }],
  receivedFriendRequests: [{ type: Schema.Types.ObjectId, ref: 'User' }],
  sentFriendRequests: [{ type: Schema.Types.ObjectId, ref: 'User' }],
  sharedFriendCheckIns: [{ type: Schema.Types.ObjectId, ref: 'User' }],
  resetPasswordToken: String,
  resetPasswordExpires: Date,
  emailConfirmToken: String,
  emailConfirmExpires: Date,
  emailConfirmed: {
    type: Boolean,
    default: false
  }
})
....

UserSchema.index({ firstName: 'text', lastName: 'text', email: 'text'})

var User = module.exports = mongoose.model('User', UserSchema)

我做错了什么还是有什么方法可以实现所有 5 个案例?

【问题讨论】:

  • 你找到解决办法了吗?
  • 是的,下面你有解决方案。

标签: mongodb search text


【解决方案1】:

如果有人需要,我已经解决了这个问题。由于我是初学者,因此解决方案很简单,可能不是最佳的,但它可以做到。

FriendController.route('/').get(passport.authenticate('jwt', { session: false }), function (req, res) {

var parts = (req.query.keyWord).split(' ')
var firstName = ''
var lastName = ''

if (parts.length > 1) {

  firstName = (req.query.keyWord).split(' ').slice(0, -1).join(' ')
  lastName = (req.query.keyWord).split(' ').slice(-1).join(' ')

} else {

  firstName = req.query.keyWord
  lastName = req.query.keyWord

}

User.find({
  $and: [
    {
      $or: [
        {
          firstName: { $regex: firstName, $options: 'i'}
        },
        {
          lastName: { $regex: lastName, $options: 'i'}
        },
        {
          email: req.query.keyWord
        }
      ]
    },
    {
      friends: req.user.id
    }
  ]
})
  .select('firstName lastName email avatarPath facebookID')
  .exec(function (err, friends) {
    if (err) {
      logger.error('Friend 500 ' + err)
      return res.status(500).json({
        code: config.errorCode.status500.code,
        message: config.errorCode.status500.message
      })
    }
    User.find({
      $and: [
        {
          $or: [
            {
              firstName: { $regex: firstName, $options: 'i'}
            },
            {
              lastName: { $regex: lastName, $options: 'i'}
            },
            {
              email: req.query.keyWord
            }
          ]
        },
        {
          sentFriendRequests: req.user.id
        }
      ]
    })
      .select('firstName lastName email avatarPath facebookID')
      .exec(function (err, friendRequests) {
        if (err) {
          logger.error('Friend 500 ' + err)
          return res.status(500).json({
            code: config.errorCode.status500.code,
            message: config.errorCode.status500.message
          })
        }
        return res.json({
          receivedFriendRequests: friendRequests,
          data: friends
        })
      })
  })
})

【讨论】:

    【解决方案2】:

    尝试使用这段代码,我已将正则表达式替换为 $text

    User.findOne({ _id: req.user.id })
                  .populate({
                    path: 'friends',
                    select: 'firstName lastName email avatarPath facebookID',
                    match: 
                      { $text: { $search: req.query.keyWord } }
                  })
                  .populate({
                    path: 'receivedFriendRequests',
                    select: 'firstName lastName email avatarPath facebookID',
                    match: {
                       $text: { $search: req.query.keyWord } 
                    }
                  })
                  .exec(function (err, user) {
                    if (err) {
                      logger.error('Friend 500 ' + err)
                      return res.status(500).json({
                        code: config.errorCode.status500.code,
                        message: config.errorCode.status500.message
                      })
                    }
                    if (!user) {
                      logger.error('Friend 404 User does not exist.')
                      return res.status(404).json({
                        code: config.errorCode.status404.code,
                        message: config.errorCode.status404.message
                      })
                    }else {
                      if (!user.friends) {
                        logger.error('Friend 404 User friends do not exist.')
                        return res.status(404).json({
                          code: config.errorCode.status404.code,
                          message: config.errorCode.status404.message
                        })
                      }
                      return res.json({
                        receivedFriendRequests: user.receivedFriendRequests.slice(0, 5),
                        data: user.friends
                      })
                    }
                  })
    

    【讨论】:

    • 我已经尝试过这种方式,但它不适用于案例 1 和案例 3,您可以在我的第一个代码块中看到它,但无论如何感谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-11-20
    • 1970-01-01
    • 2011-08-19
    • 1970-01-01
    • 1970-01-01
    • 2012-02-19
    • 1970-01-01
    相关资源
    最近更新 更多