关于javascript:将$ or与$ elemMatch一起使用,并在Array之外使用条件

Use $or with $elemMatch and condition outside of Array

我的基本结构是,我有一个带有会话对象的User对象,该会话对象包含subjectId和每小时价格。

1
2
3
4
5
6
7
8
9
User{
    defaultHourly: Number,
    subjects{
        [
            id: String,
            hourly: Number
        ]
    }
}

我这样使用elemMatch:

1
2
3
4
5
6
7
8
9
10
11
12
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不是主题中的字段,而是主题的父级中的一个字段,因此我不确定如何访问它。

我要写:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
"$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 } }
                ]
            }
       ]
 });

如何进行多级比较?


您将条件写在$elemMatch之外,然后将$or放在文档的顶层。这允许每个"组"条件都适用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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,因为" range "比较实际上将否定null,因为它根本不会比实际数值"大"。

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

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

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