概述
在工作中有時(shí)遇到這么一種場景 找出那些字段A和字段B相等的數(shù)據(jù)
剛開始只能想到自己聯(lián)表查自己,后面研究了一下,發(fā)現(xiàn)了更簡單的方法,分享出來
測試數(shù)據(jù)
假設(shè)我們有以下測試數(shù)據(jù)

是一張暗戀表,有人喜歡別人,有人自戀
我們現(xiàn)在想要找出那些自戀的人
思路1-聯(lián)表
根據(jù)語法和常規(guī)思路,我們寫下了如下查詢
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 是用來拍平數(shù)據(jù)結(jié)構(gòu)的,因?yàn)槁?lián)表之后,嵌套字段是一個(gè)列表)
查詢之后發(fā)現(xiàn)結(jié)果為空
嗯?我們把 match 刪了看一下結(jié)果是啥

可以看到,聯(lián)表的確是生效了,但是我們要找的是自戀, 而不是 有人愛,
聯(lián)表之后還差一步,就是找到name 等于 love_yourself.name 的記錄
但是,等等,貌似又回到了最初的問題: 找到字段相等的數(shù)據(jù)
所以,聯(lián)表也遇到同樣的問題,也就是聯(lián)表并沒有解決這個(gè)問題,所以此路不通
思路2 - $expr
然后在官方文檔的 query 里面找啊找,發(fā)現(xiàn)了 expr 的操作,例子很有意思

然后我想,我把 gt 換成 eq 行不行呢
把查詢語句換一下
db.getCollection("field_equals").find({
$expr: {
$eq: ["$name", "$love"]
}
})
結(jié)果如下

bingo! 可以了
思路3
這個(gè)問題暫時(shí)解決了,但是平時(shí)工作中,經(jīng)常遇到 ObjectId 和 String 互相匹配的問題
那么在這種場景下,語句如何寫呢?
我們準(zhǔn)備好測試數(shù)據(jù)

可以看到
love 字段全部是 String 類型的切為表格模式,標(biāo)注一下

值一樣的,標(biāo)記為了同一個(gè)顏色
我們先來試一下,思路不變,能不能查出來(語句有變化,字段換成了_id)

很遺憾,不能
此時(shí)還是在 expr 的文檔里看到了這么一個(gè)例子

很明顯,$expr 的 參數(shù)列表,參數(shù)類型可以是 轉(zhuǎn)換函數(shù),不一定就需要是老老實(shí)實(shí)的字段, 如圖中就是用了 $cond 作為條件函數(shù)來轉(zhuǎn)換字段,
那么我把 ObjectId 轉(zhuǎn)為 String 類型的是不是就可以了呢
來試一下以下的查詢語句
db.getCollection("field_equals").find({
$expr: {
$eq: [
{
$toString: "$_id"
},
"$love"
]
}
})
結(jié)果如下

OK,這個(gè)場景也解決了