Skip to content

MongoDB 从数组型字段中选出符合要求的元素 #148

@Dream4ever

Description

@Dream4ever

问题描述

用户表的定义如下:

const userSchema = new mongoose.Schema(
  {
    openid: {
      type: String,
      required: true,
      unique: true,
      index: true,
    },
    score: [{
      game: String,
      record: Number,
    }],
  },
)

现在需要选出 score 字段的 game 属性为指定值的记录。

并且由于 score 是数组类型的字段,要求返回的结果只包含 game 属性为指定值的那一条记录(数组中各元素的 game 属性各不相同),其余记录全都不需要。

解决方案

方案一:$ 方法

const rank = await User.find({
  "score.game": {
    $eq: gameId,
  },
},
{
  "score.$": 1,
})
  .select('-_id openid score')
  .lean()
  .exec()

以上代码可以满足要求,但是从数据库返回的结果中,无法通过 select 语句来将用不到的 _idgame 字段剔除,即返回的是如下格式的结果:

{
    "openid": "oOHGX6VyNNtywCOQE9hW98Gp49sM",
    "score": [
        {
            "_id": "60ab6a25a2f621284869c95a",
            "game": "game2",
            "record": 37
        }
    ]
}

方案二:$elemMatch 方法

const rank = await User.find({
  'score.game': gameId
},
{
  score: {
    $elemMatch: {
      game: gameId,
    },
  },
})
  .select('-_id openid score.record')
  .lean()
  .exec()

该方法效果更佳,可以通过 select 方法,只保留需要的子字段,返回结果格式如下:

{
  "openid": "oOHGX6VyNNtywCOQE9hW98Gp49sM",
  "score": [
    {
      "record": 37
    }
  ]
}

综合考虑,选择方案二。

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions