mongodb $exists 在 mongodb 的 $expr 中
Posted
技术标签:
【中文标题】mongodb $exists 在 mongodb 的 $expr 中【英文标题】:Mongodb $exists inside $expr in mongodb 【发布时间】:2022-01-24 05:26:33 【问题描述】:我想在加入时添加多个条件。加入满足以下条件的文档(属于同一集合):
-
有异性
在主文档年龄偏好和主文档之间有年龄(如果存在)在外国文档偏好之间有
age
(如果存在)(即双向检查)
我的尝试如下,但有两个问题:
$exists
不能在 $expr
里面使用,为什么
年龄查询是目前的一种方式
$lookup:
"from": "appusers",
"let": 'gen': "$gender",'pref': "$preference" ,
"pipeline": [
$match: $expr:
$and: [
$ne: ["$gender", "$$gen"],
$or: [
$exists: "$age": false,
$and: [
$gte: ["$age", '$$pref.age_from' ] ,
$lte: [ "$age", '$$pref.age_to' ]
]
]
]
],
"as": "matches"
示例: 输入文档:
name: "person1",
age: 36,
gender: "Male",
preference:
age_from: 25,
age_to: 35
name: "person2",
age: 18,
gender: "Female",
preference:
age_from: 25,
age_to: 40
name: "person3",
age: 26,
gender: "Female",
preference:
age_from: 30,
age_to: 35
name: "person4",
age: 26,
gender: "Female",
preference:
age_from: 30,
age_to: 40
输出: 对于第 1 个人,匹配数组将仅显示第 4 个人(同样第 4 个人匹配将显示第 1 个人),即:
name: person1,
age: 36,
gender: "Male",
preference:
age_from: 28,
age_to: 35
,
matches: [
name: person4,
...
]
我查看了 this 和 this 但没有帮助
【问题讨论】:
也许看看***.com/questions/68255363/or-with-if-and-in-mongodb/… 我们可以提供一些示例数据集和预期输出吗? @ray 我已经添加了示例数据 【参考方案1】:
$exists
不能在$expr
里面使用 idk 为什么
$expr 允许在查询语言中使用聚合表达式,而$exists 不是聚合运算符,
你只需要纠正两件事:
将$expr
条件放在第一个$and
条件中
将$expr
放在最后一个$and
条件中
db.appusers.aggregate([
$lookup:
from: "appusers",
let: gen: "$gender", pref: "$preference" ,
pipeline: [
$match:
$and: [
$expr: $ne: ["$gender", "$$gen"] ,
$or: [
age: $exists: false ,
$expr:
$and: [
$gte: ["$age", "$$pref.age_from"] ,
$lte: ["$age", "$$pref.age_to"]
]
]
]
],
as: "matches"
])
Playground
【讨论】:
【参考方案2】:对于$exists
问题,你可以用$ifNull
包裹age
,并使用$eq
来检查是否存在。
对于 2 路年龄匹配,我认为您只需要从 person1 到 person4 重复从 person4 到 person1 的年龄匹配标准。尽管在您当前给定的测试用例中,找不到匹配项,因为 person4 的年龄超出了 person1 的偏好。
db.appusers.aggregate([
"$match":
name: "person1"
,
$lookup:
"from": "appusers",
"let":
"a": "$age",
"gen": "$gender",
"pref": "$preference"
,
"pipeline": [
$match:
$expr:
$and: [
$ne: [
"$$gen",
"$gender"
]
,
$and: [
$or: [
$eq: [
"$ifNull": [
"$age",
"age-not-exists"
]
,
"age-not-exists"
]
,
$and: [
$gte: [
"$age",
"$$pref.age_from"
]
,
$lte: [
"$age",
"$$pref.age_to"
]
]
]
,
$or: [
$eq: [
"$ifNull": [
"$$a",
"age-not-exists"
]
,
"age-not-exists"
]
,
$and: [
$gte: [
"$$a",
"$preference.age_from"
]
,
$lte: [
"$$a",
"$preference.age_to"
]
]
]
]
]
],
"as": "matches"
])
这是Mongo playground 供您参考。
【讨论】:
对不起!你是对的。我现在更新了 person1 的年龄偏好 @artsnr This 应该适用于您更新后的 person1 年龄偏好。 如果偏好不存在,它不适应这种情况....需要对年龄和偏好进行存在检查。如果两者都存在,则进行比较,否则不进行比较并包含文档 @artsnr 你能用你的新测试用例更新这个问题吗?【参考方案3】:您可以对字段年龄使用 $eq undefined 而不是 $exists
"from": "appusers",
"let": 'gen': "$gender",'pref': "$preference" ,
"pipeline": [
$match: $expr:
$and: [
$ne: ["$gender", "$$gen"],
$or: [
$eq: ["$age" , undefined],
$and: [
$gte: ["$age", '$$pref.age_from' ] ,
$lte: [ "$age", '$$pref.age_to' ]
]
]
]
],
"as": "matches"
【讨论】:
以上是关于mongodb $exists 在 mongodb 的 $expr 中的主要内容,如果未能解决你的问题,请参考以下文章