概述
在工作中有时遇到这么一种场景 找出那些字段A和字段B相等的数据
刚开始只能想到自己联表查自己,后面研究了一下,发现了更简单的方法,分享出来
测试数据
假设我们有以下测试数据
image.png
是一张暗恋表
,有人喜欢别人,有人自恋
我们现在想要找出那些自恋的人
思路1-联表
根据语法和常规思路,我们写下了如下查询
db.getCollection("field_equals").aggregate([
{
$lookup: {
from: "field_equals",
localField: "name",
foreignField: "love",
as: "love_yourself"
}
},{
$unwind: "$love_yourself"
},
{
$match: {
name: "$love_yourself.name"
}
}
])
($unwind
是用来拍平数据结构的,因为联表之后,嵌套字段是一个列表)
查询之后发现结果为空
嗯?我们把 match
删了看一下结果是啥
可以看到,联表的确是生效了,但是我们要找的是自恋
, 而不是 有人爱
,
联表之后还差一步,就是找到name
等于 love_yourself.name
的记录
但是,等等,貌似又回到了最初的问题: 找到字段相等的数据
所以,联表也遇到同样的问题,也就是联表并没有解决这个问题,所以此路不通
思路2 - $expr
然后在官方文档的 query 里面找啊找,发现了 expr
的操作,例子很有意思
然后我想,我把 gt
换成 eq
行不行呢
把查询语句换一下
db.getCollection("field_equals").find({
$expr: {
$eq: ["$name", "$love"]
}
})
结果如下
image.png
bingo! 可以了
思路3
这个问题暂时解决了,但是平时工作中,经常遇到 ObjectId
和 String
互相匹配的问题
那么在这种场景下,语句如何写呢?
我们准备好测试数据
image.png可以看到
love
字段全部是 String
类型的切为表格模式,标注一下
image.png
值一样的,标记为了同一个颜色
我们先来试一下,思路不变,能不能查出来(语句有变化,字段换成了_id
)
很遗憾,不能
此时还是在 expr
的文档里看到了这么一个例子
很明显,$expr
的 参数列表,参数类型可以是 转换函数,不一定就需要是老老实实的字段, 如图中就是用了 $cond
作为条件函数来转换字段,
那么我把 ObjectId
转为 String
类型的是不是就可以了呢
来试一下以下的查询语句
db.getCollection("field_equals").find({
$expr: {
$eq: [
{
$toString: "$_id"
},
"$love"
]
}
})
结果如下
image.png
OK,这个场景也解决了
网友评论