【问题标题】:Use $or with $elemMatch and condition outside of Array将 $or 与 $elemMatch 和 Array 外的条件一起使用
【发布时间】:2017-11-30 21:39:30
【问题描述】:

我的基本结构是我有一个用户对象和一个会话对象,其中包含一个 subjectId 和一个小时价格。

User{
    defaultHourly: Number,
    subjects{
        [
            id: String,
            hourly: Number
        ]
    }
}    

我是这样使用 elemMatch 的:

query.elemMatch("subjects", {
                "id": { $in: subjects },
                "$or": [
                    { "hourly": { $eq: null } }, // this is my issue
                    {
                        "$and": [
                            { "hourly": { $ne: null } },
                            { "hourly": { $gte: price.low, $lte: price.high } }
                        ]
                    }
                ]
            });

elemMatch 的第一部分确保我想要的 subjectId 在主题数组中。然后我想按价格过滤。如果用户在每小时字段中为空,我想将 defaultHourly 与 price.low 和 price.high 进行比较。

问题是 defaultHourly 不是主题中的字段,而是主题父项中的字段,因此我不确定如何访问它。

我想写:

"$or": [
           { 
                "$and": [
                   { "hourly": { $eq: null } },
                   { "defaultHourly": { $gte: price.low, $lte: price.high } } //this doesnt work because default hourly is not a field.
                ]
           },
           {
               "$and": [
                   { "hourly": { $ne: null } },
                   { "hourly": { $gte: price.low, $lte: price.high } }
                ]
            }
       ]
 }); 

如何进行这种多级比较?

【问题讨论】:

    标签: javascript node.js mongodb mongoose mongodb-query


    【解决方案1】:

    您在$elemMatch 之外编写条件,并将$or 放在文档的顶层。这允许应用每“组”条件:

    User.find({
      "$or": [
         { 
           "defaultHourly": { "$gte": price.low, "$lte": price.high },
           "subjects": {
             "$elemMatch": { 
               "id": { "$in": subjects },
               "hourly": { "$eq": null }
             }
           }
         },
         {
           "subjects": {
             "$elemMatch": {
               "id": { "$in": subjects },
               "hourly": { "$gte": price.low, "$lte": price.high }
             }
           }
         }
      ] 
    })
    

    还请注意,不需要$ne,因为“范围”比较实际上会否定null,因为它根本不会“大于”实际数值。

    另外,请注意所有 MongoDB 查询表达式已经是 AND 条件,例如同一属性上的 $gte$lte。所以即使不是必须的,$ne 也可以写成:

       "hourly": { "$gte": price.low, "$lte": price.high, "$ne": null }
    

    这消除了对显式 $and 的任何需要。

    【讨论】:

      猜你喜欢
      • 2013-12-12
      • 1970-01-01
      • 2019-03-17
      • 1970-01-01
      • 1970-01-01
      • 2014-08-21
      • 1970-01-01
      • 2015-02-14
      • 1970-01-01
      相关资源
      最近更新 更多