$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所以如果你愿意,你可以跟踪它。

现在认为您有两个选择。

  1. 将您的调用拆分为 2 个查询,然后将那部分逻辑添加到您的代码中,这是我个人推荐的做法。

  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"
                }
            }
        }
    }
])

您可能已经注意到管道并不十分吸引人,如果您不关心最终结果中的字段名称,您可以转储其中的大部分内容。