【问题标题】:Return Mongo document using Mongoose where subdocument does NOT exist?在不存在子文档的情况下使用 Mongoose 返回 Mongo 文档?
【发布时间】:2015-10-10 21:48:21
【问题描述】:

帮助!我正在失去理智。我需要简单地返回一个 Mongo document,使用 MongooseIF 子文档不存在。

我的架构:

var userSchema = new mongoose.Schema({
    email: {type: String, unique: true, lowercase: true},
    password: {type: String, select: false},
    displayName: String,
    picture: String,
    facebook: String,
    deactivation: deactiveSchema
});

var deactiveSchema = new mongoose.Schema({
    when : { type: Date, default: Date.now, required: true },
    who  : { type: Schema.Types.ObjectId, required: true, ref: 'User' }
});

我的目标是通过facebook ID 查找未停用的用户。

如果它们被停用,则将存在deactivation 子文档。当然,为了节省空间,如果它们处于活动状态,那么 deactivation存在。

顺便说一句,我也担心如何正确地构建这个逻辑上的索引。

我会发布 sn-ps,但每次尝试都是错误的。 =(

【问题讨论】:

  • 返回那个用户文档然后检查if (user.deactivation)怎么样?数据的用例将为您指明正确的方向。
  • 理论上,如果我只查询 FB ID,然后在返回文档后检查文档,我可能会返回多个文档。来自 RDBMS 世界,我认为正确/最优雅的方法是以某种方式使用索引来查找匹配条件的 ONE 用户。但是,现在我想到了,是否甚至可以在索引中包含子文档信息?嗯...伙计,菜鸟有时很痛苦。 :P
  • 您不能通过简单地使用审计字段来完成相同的任务吗?例如,拥有一个 dateDeactivated 字段将允许您索引这两个字段,而无需处理子文档。
  • 我最近也为一个项目选择了 MongoDB。 Mongoose 为 Node.js 提供了一个非常简单的界面。我发现它还需要开发人员将大部分数据库逻辑转移到应用程序层。在您的情况下,我认为要么返回除密码之外的所有内容,要么只返回 facbook 和 deactivation 并且 if (!deactivation) 为文档发出另一个查询。它并不优雅,但在 NoSQL 领域的查询要快得多。感谢@G.Deward 编辑
  • 也许我错过了什么;如果您通过 FB Id 查询,则该字段应限制为唯一。如果它是唯一的,您将使用findOne() 而不是find()。然后,当您返回一个文档时,您就可以在内存中检查它。

标签: node.js mongodb mongoose


【解决方案1】:

你可以使用$exists操作符:

 userSchema.find({deactivation:{$exists:false}}).exec(function(err,document){


  });

$ne:

 userSchema.find({deactivation:{$ne:null}}).exec(function(err,document){


  });

【讨论】:

    【解决方案2】:

    由于您要停用数据而不是删除,我会采用以下两种方法之一:

    退休标志 (推荐)

    添加到您的架构:

    retired: {
        type: Boolean,
        required: true
    }
    

    并为此查询添加索引:

    userSchema.index({facebook: 1, retired: 1})
    

    和查询:

    User.find({facebook: facebookId, retired: false}, callback)
    

    查询是否存在

    User.find().exists("deactivation", false).exec(callback)
    

    后者会慢一些,但如果你真的不想改变任何东西,它会起作用。我建议花一些时间阅读 mongo 文档的 indexing 部分。

    【讨论】:

      【解决方案3】:

      Mongoose 有许多选项用于定义带有条件的查询和几种编写查询的样式:

      条件对象

      var id = "somefacebookid";
      
      var condition = {
        facebook : id, 
        deactivation: { $exists : true}
      };
      
      user.findOne(condition, function (e, doc) {
           // if not e, do something with doc
      }) 
      

      http://mongoosejs.com/docs/queries.html

      查询生成器

      或者,如果您正在寻找更接近 SQL 的内容,您可能希望使用查询构建器语法。例如:

      var id = "somefacebookid"; 
      users
          .find({ facebook : id }).
          .where('deactivation').exists(false)
          .limit(1)
          .exec(callback);
      

      【讨论】:

      • 这不需要在文档中专门将deactivation 设置为null 吗?据我了解,如果deactivation 子文档根本不存在,这将失败,因为您正在专门检查null。对吗?
      • 是的,这很好。我主要是想展示使用猫鼬执行“类似sql”的查询的两种方式。即通过使用条件对象或链接类似 sql 的命令。但你是对的,我会更新undefined
      猜你喜欢
      • 2014-11-20
      • 2016-01-23
      • 1970-01-01
      • 1970-01-01
      • 2014-04-07
      • 2020-11-12
      • 1970-01-01
      • 2015-11-29
      • 2016-02-23
      相关资源
      最近更新 更多