找到 Mongoose 后

wmtdaxz3  于 2022-11-13  发布在  Go
关注(0)|答案(3)|浏览(118)

在使用mongoose填充文档后,我在通过文档内部的匹配值查询文档时遇到了一些问题。
我的模式如下:

var EmailSchema = new mongoose.Schema({
  type: String
});

var UserSchema = new mongoose.Schema({
  name: String,
  email: [{type:Schema.Types.ObjectId, ref:'Email'}]
});

我想有一个电子邮件类型为“Gmail”的所有用户为例。
以下查询返回空结果:

Users.find({'email.type':'Gmail').populate('email').exec( function(err, users)
    {
      res.json(users);
    });

我不得不在JS中采用如下方式过滤结果:

users = users.filter(function(user)
        {
          for (var index = 0; index < user.email.length; index++) {
            var email = user.email[index];
            if(email.type === "Gmail")
            {
              return true;
            }
          }
          return false;
        });

有没有办法直接从 Mongoose 那里查询到这样的东西?

mwngjboj

mwngjboj1#

@Jason Cust已经解释得很清楚了-在这种情况下,最好的解决方案通常是更改模式,以防止通过存储在单独集合中的文档的属性来查询Users

这是我能想到的最好的解决方案,不会强迫你这样做,虽然(因为你在评论中说,你不能)。

Users.find().populate({
  path: 'email',
  match: {
    type: 'Gmail'
  }
}).exec(function(err, users) {
  users = users.filter(function(user) {
    return user.email; // return only users with email matching 'type: "Gmail"' query
  });
});

我们在这里所做的是只填充email的匹配附加查询(.populate()调用中的match选项)-否则Users文档中的email字段将被设置为null
剩下的就是返回的users数组上的.filter,就像你最初的问题一样--只是有一个更简单、更通用的检查。

8nuwlpux

8nuwlpux2#

Mongoose的populate函数并不直接在Mongo中执行,而是在初始的find查询返回一组文档之后,populate将在引用的集合上创建一个find查询数组,然后执行并将结果合并到原始文档中。(尚未提取,因此为undefined)来过滤原始结果集。
在此用例中,将电子邮件存储为子文档数组而不是单独的集合来实现您想要的功能似乎更合适。此外,作为一种通用的文档存储设计模式,这是将数组存储为子文档有意义的用例之一:有限的尺寸和很少的修改。
正在将架构更新为:

var EmailSchema = new mongoose.Schema({
  type: String
});

var UserSchema = new mongoose.Schema({
  name: String,
  email: [EmailSchema]
});

那么下面的查询应该可以工作:

Users.find({'email.type':'Gmail').exec(function(err, users) {
  res.json(users);
});
uubf1zoe

uubf1zoe3#

我找不到任何其他的解决方案,除了使用聚合。这将是更麻烦的,但我们将使用查找。

{
       $lookup:
         {
           from: <collection to join>,
           localField: <field from the input documents>,
           foreignField: <field from the documents of the "from" collection>,
           as: <output array field>
         }
}

相关问题