MongoDB 聚合匹配 ObjectId 与字符串
MongoDB aggregation matching ObjectId against string
我有以下文档,也可以在 mongo 操场上找到:
https://mongoplayground.net/p/zhcoi1BF0Ny
db={
MyCollectionOne: [
{
"firstId": "10",
"secondId": "123456789012345678901234"
},
{
"firstId": "11",
"secondId": "999999999999999999999999"
}
],
MyCollectionTwo: [
{
"_id": ObjectId("123456789012345678901234"),
"otherFieldOne": "Some Data",
"otherFieldTwo": [
{
someNumber: 7
}
]
},
{
"_id": ObjectId("999999999999999999999999"),
"otherFieldOne": "Some Other Data",
"otherFieldTwo": [
{
someNumber: 9
},
{
someNumber: 39
}
]
}
]
}
给定一个 firstId,我需要确定 return 的正确 MyCollectionTwo 条目。因此,例如,如果我的 firstId 为 11,我将使用它来查找其对应的 secondId(即“999999999999999999999999”)。我需要将 secondId 值转换为 ObjectId,然后查看 MyCollectionTwo _id 字段,直到找到匹配的字段。
我尝试了一下,非常接近,但无法弄清楚如何正确地进行 string->objectId 转换。
db.MyCollectionTwo.aggregate([
{
$lookup: {
from: "MyCollectionOne",
localField: "_id",
foreignField: "secondId",
as: "Temp"
}
},
{
$unwind: "$Temp"
},
{
$match: {
"Temp.firstId": "11"
}
},
{
$project: {
_id: 1,
otherFieldOne: 1,
otherFieldTwo: 1
}
}
]).find()
我知道有一个 let/pipeline 可以使用 $toObjectId 但我无法在上述上下文中使用它。
如有任何帮助,我们将不胜感激。谢谢!
您的 $lookup
with pipeline 应该如下所示:
$lookup: {
from: "MyCollectionOne",
let: {
id: "$_id"
},
pipeline: [
{
$match: {
$expr: {
$eq: [
{
$toObjectId: "$secondId"
},
"$$id"
]
}
}
}
],
as: "Temp"
}
你可以试试这个
db.MyCollectionTwo.aggregate([
{
$lookup: {
//searching collection name
from: "MyCollectionOne",
//setting variable [searchId] where your string converted to ObjectId
let: {
"searchId": {
$toObjectId: "$secondId"
}
},
//search query with our [searchId] value
"pipeline": [
//searching [searchId] value equals your field [_id]
{
"$match": {
"$expr": [
{
"_id": "$$searchId"
}
]
}
},
],
as: "Temp"
}
},
{
$unwind: "$Temp"
},
{
$match: {
"Temp.firstId": "11"
}
},
{
$project: {
_id: 1,
otherFieldOne: 1,
otherFieldTwo: 1
}
}
]).find()
我有以下文档,也可以在 mongo 操场上找到: https://mongoplayground.net/p/zhcoi1BF0Ny
db={
MyCollectionOne: [
{
"firstId": "10",
"secondId": "123456789012345678901234"
},
{
"firstId": "11",
"secondId": "999999999999999999999999"
}
],
MyCollectionTwo: [
{
"_id": ObjectId("123456789012345678901234"),
"otherFieldOne": "Some Data",
"otherFieldTwo": [
{
someNumber: 7
}
]
},
{
"_id": ObjectId("999999999999999999999999"),
"otherFieldOne": "Some Other Data",
"otherFieldTwo": [
{
someNumber: 9
},
{
someNumber: 39
}
]
}
]
}
给定一个 firstId,我需要确定 return 的正确 MyCollectionTwo 条目。因此,例如,如果我的 firstId 为 11,我将使用它来查找其对应的 secondId(即“999999999999999999999999”)。我需要将 secondId 值转换为 ObjectId,然后查看 MyCollectionTwo _id 字段,直到找到匹配的字段。
我尝试了一下,非常接近,但无法弄清楚如何正确地进行 string->objectId 转换。
db.MyCollectionTwo.aggregate([
{
$lookup: {
from: "MyCollectionOne",
localField: "_id",
foreignField: "secondId",
as: "Temp"
}
},
{
$unwind: "$Temp"
},
{
$match: {
"Temp.firstId": "11"
}
},
{
$project: {
_id: 1,
otherFieldOne: 1,
otherFieldTwo: 1
}
}
]).find()
我知道有一个 let/pipeline 可以使用 $toObjectId 但我无法在上述上下文中使用它。
如有任何帮助,我们将不胜感激。谢谢!
您的 $lookup
with pipeline 应该如下所示:
$lookup: {
from: "MyCollectionOne",
let: {
id: "$_id"
},
pipeline: [
{
$match: {
$expr: {
$eq: [
{
$toObjectId: "$secondId"
},
"$$id"
]
}
}
}
],
as: "Temp"
}
你可以试试这个
db.MyCollectionTwo.aggregate([
{
$lookup: {
//searching collection name
from: "MyCollectionOne",
//setting variable [searchId] where your string converted to ObjectId
let: {
"searchId": {
$toObjectId: "$secondId"
}
},
//search query with our [searchId] value
"pipeline": [
//searching [searchId] value equals your field [_id]
{
"$match": {
"$expr": [
{
"_id": "$$searchId"
}
]
}
},
],
as: "Temp"
}
},
{
$unwind: "$Temp"
},
{
$match: {
"Temp.firstId": "11"
}
},
{
$project: {
_id: 1,
otherFieldOne: 1,
otherFieldTwo: 1
}
}
]).find()