【问题标题】:MongoDb Query on array field of a nested objectMongoDb查询嵌套对象的数组字段
【发布时间】:2019-05-17 09:15:24
【问题描述】:

我正在尝试查询收藏某个活动的所有用户。事件 ID 存储在嵌套对象的用户文档中。

我的架构是这样的

{
    email: {
      type: String,
      unique: true,
      required: [true, 'Email is required!'],
      trim: true,
      validate: {
        validator(email) {
          const emailRegex = /^[-a-z0-9%S_+]+(\.[-a-z0-9%S_+]+)*@(?:[a-z0-9-]{1,63}\.){1,125}[a-z]{2,63}$/i;
          return emailRegex.test(email);
        },
        message: '{VALUE} is not a valid email!',
      },
    },
    role: {
      type: String,
      enum: ['admin', 'user', 'planner'],
      default: 'user',
    },
    name: {
      type: String,
      trim: true,
    },
    username: {
      type: String,
      trim: true,
      unique: true,
    },
    password: {
      type: String,
      required: [true, 'Password is required!'],
      trim: true,
      minlength: [6, 'Password needs to be longer!'],
      validate: {
        validator(password) {
          return password.length >= 6 && password.match(/\d+/g);
        },
      },
    },
    picture: {type: String},
    favorites: {
      events: [
        {
          type: Schema.Types.ObjectId,
          ref: 'Event',
        },
      ],
    },
  }

我将如何编写这个查询?

我已经尝试了$elemMatch 和普通查询的各种组合

【问题讨论】:

  • db.collection.find({ "favorites.events": userId })
  • 感谢@AnthonyWinzlet 出人意料地奏效了,问题是我之前尝试过时传递的是字符串而不是传递对象ID!

标签: arrays node.js mongodb express mongoose


【解决方案1】:

$elemMatch 应该作为一个对象使用,但是在数组favorites.events 中每个元素都是字符串(ObjectID),所以你应该使用$eq 将每个元素与你想要的事件ID 匹配。

解决办法是:

User.find({
    'favorites.events': {
        '$elemMatch': {
            '$eq': id
        }
    }
})

$elemMatch 的文档在这里https://docs.mongodb.com/manual/reference/operator/query/elemMatch/#element-match

$eq 的文档在这里https://docs.mongodb.com/manual/reference/operator/query/eq/

你应该对 Mongo 的简单结构提出质疑。例如,这是我为你测试的问题

const Schema = mongoose.Schema;

const EventSchema = new Schema({
    title: String
})

const UserSchema = new Schema({
    username: String,
    favorites: {
        events: [{
            type: Schema.Types.ObjectId,
            ref: 'Event',
        }]
    }
});

const User = mongoose.model('User', UserSchema);
const Event = mongoose.model('Event', EventSchema)

app.get('/users/event/:id', (req, res) => {
    const {id} = req.params;
    console.log(id);
    User.find({
        'favorites.events': {
            '$elemMatch': {
                '$eq': id
            }
        }
    }).then(u => res.send(u)) })

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-07-23
    • 2016-09-05
    • 1970-01-01
    • 2018-11-01
    • 2018-09-10
    • 2021-01-24
    • 1970-01-01
    • 2020-03-28
    相关资源
    最近更新 更多