$lookup 中的动态
Dynamic from in $lookup
我正在尝试查看是否可以更改 $lookup 中的 from 或重新安排我的查询以某种方式从三个潜在的检索collection秒。到目前为止,我已经成功地设置了这样的查询:
const search = db.collection("search");
search.aggregate([
{
'$match': {
'id_int': 0
}
}, {
'$project': {
'_id': 0,
'collection': 1,
'id_int': 1
}
}, {
'$lookup': {
'from': 'arxiv',
'localField': 'id_int',
'foreignField': 'id_int',
'as': 'arxiv'
}
}
], function(err, cursor) ... )
$match 然后 $project 管道阶段 return 具有以下属性的结果:
collection:"arxiv"
id_int:0
collection 值将始终是三个 arxiv、crossref 或 pmc_test 之一。因此,我希望我的 $lookup from 以编程方式使用此 属性 值,而不是对其进行硬编码。
'$lookup': {
'from': 'arxiv' or 'crossref' or 'pmc_test', // Dynamic based on result
...
}
谢谢
编辑
id_int 将被传递而 collection 不会,这就是为什么对搜索 collection.
进行查询的原因
遗憾的是,目前这不可能,有一个开放的功能请求here所以如果你愿意,你可以跟踪它。
现在认为您有两个选择。
将您的调用拆分为 2 个查询,然后将那部分逻辑添加到您的代码中,这是我个人推荐的做法。
使用此聚合查找所有 3 个集合:
search.aggregate([
{
'$match': {
'id_int': 0
}
},
{
'$project': {
'_id': 0,
'collection': 1,
'id_int': 1
}
},
{
"$facet": {
"arxiv": [
{
"$lookup": {
"from": "arxiv",
"localField": "id_int",
"foreignField": "id_int",
"as": "arxiv"
}
}
],
"crossref": [
{
"$lookup": {
"from": "crossref",
"localField": "id_int",
"foreignField": "id_int",
"as": "crossref"
}
}
],
"pmc_test": [
{
"$lookup": {
"from": "pmc_test",
"localField": "id_int",
"foreignField": "id_int",
"as": "pmc_test"
}
}
]
}
},
{
"$addFields": {
"newRoot": [
{
"k": "$collection",
"v": {
"$cond": [
{
"$eq": [
"$collection",
"arxiv"
]
},
"$arxiv",
{
"$cond": [
{
"$eq": [
"$collection",
"crossref"
]
},
"$crossref",
"$pmc_test"
]
}
]
}
},
{
"k": "collection", "v": "$collection"
},
{
"k": "id_int", "v": "$id_int"
}
]
}
},
{
"$replaceRoot": {
"newRoot": {
"$arrayToObject": {
"$concatArrays": "$newRoot"
}
}
}
}
])
您可能已经注意到管道并不十分吸引人,如果您不关心最终结果中的字段名称,您可以转储其中的大部分内容。
我正在尝试查看是否可以更改 $lookup 中的 from 或重新安排我的查询以某种方式从三个潜在的检索collection秒。到目前为止,我已经成功地设置了这样的查询:
const search = db.collection("search");
search.aggregate([
{
'$match': {
'id_int': 0
}
}, {
'$project': {
'_id': 0,
'collection': 1,
'id_int': 1
}
}, {
'$lookup': {
'from': 'arxiv',
'localField': 'id_int',
'foreignField': 'id_int',
'as': 'arxiv'
}
}
], function(err, cursor) ... )
$match 然后 $project 管道阶段 return 具有以下属性的结果:
collection:"arxiv"
id_int:0
collection 值将始终是三个 arxiv、crossref 或 pmc_test 之一。因此,我希望我的 $lookup from 以编程方式使用此 属性 值,而不是对其进行硬编码。
'$lookup': {
'from': 'arxiv' or 'crossref' or 'pmc_test', // Dynamic based on result
...
}
谢谢
编辑
id_int 将被传递而 collection 不会,这就是为什么对搜索 collection.
进行查询的原因遗憾的是,目前这不可能,有一个开放的功能请求here所以如果你愿意,你可以跟踪它。
现在认为您有两个选择。
将您的调用拆分为 2 个查询,然后将那部分逻辑添加到您的代码中,这是我个人推荐的做法。
使用此聚合查找所有 3 个集合:
search.aggregate([
{
'$match': {
'id_int': 0
}
},
{
'$project': {
'_id': 0,
'collection': 1,
'id_int': 1
}
},
{
"$facet": {
"arxiv": [
{
"$lookup": {
"from": "arxiv",
"localField": "id_int",
"foreignField": "id_int",
"as": "arxiv"
}
}
],
"crossref": [
{
"$lookup": {
"from": "crossref",
"localField": "id_int",
"foreignField": "id_int",
"as": "crossref"
}
}
],
"pmc_test": [
{
"$lookup": {
"from": "pmc_test",
"localField": "id_int",
"foreignField": "id_int",
"as": "pmc_test"
}
}
]
}
},
{
"$addFields": {
"newRoot": [
{
"k": "$collection",
"v": {
"$cond": [
{
"$eq": [
"$collection",
"arxiv"
]
},
"$arxiv",
{
"$cond": [
{
"$eq": [
"$collection",
"crossref"
]
},
"$crossref",
"$pmc_test"
]
}
]
}
},
{
"k": "collection", "v": "$collection"
},
{
"k": "id_int", "v": "$id_int"
}
]
}
},
{
"$replaceRoot": {
"newRoot": {
"$arrayToObject": {
"$concatArrays": "$newRoot"
}
}
}
}
])
您可能已经注意到管道并不十分吸引人,如果您不关心最终结果中的字段名称,您可以转储其中的大部分内容。