Node.js 按对象中已存在的数据进行查询

Node.js 按对象中已存在的数据进行查询,node.js,mongodb,aggregation-framework,Node.js,Mongodb,Aggregation Framework,我正在编写一个查询,根据“coll1”中的数据从“coll2”获取数据 Coll1具有以下数据结构: { "_id": "asdf", "name": "John", "bags": [ { "type": "typ1", "size": "siz1" }, { "type": "typ2", "size": "siz2" } ] } { _id: "qwer", coll1Name

我正在编写一个查询,根据“coll1”中的数据从“coll2”获取数据

Coll1具有以下数据结构:

{
  "_id": "asdf",
  "name": "John",
  "bags": [
    {
       "type": "typ1",
       "size": "siz1"
    },
    {
       "type": "typ2",
       "size": "siz2"
    }
  ]
}
{
  _id: "qwer",
  coll1Name: "John",
  types: ["typ1", "typ3"],
  sizes: ["siz1", "siz4"]
}
{
  _id: "zxcv",
  coll1Name: "John",
  types: ["typ2", "typ3"],
  sizes: ["siz1", "siz2"]
}
{
  _id: "fghj",
  coll1Name: "John",
  types: ["typ2", "typ3"],
  sizes: ["siz1", "siz4"]
}
Coll2具有以下数据结构:

{
  "_id": "asdf",
  "name": "John",
  "bags": [
    {
       "type": "typ1",
       "size": "siz1"
    },
    {
       "type": "typ2",
       "size": "siz2"
    }
  ]
}
{
  _id: "qwer",
  coll1Name: "John",
  types: ["typ1", "typ3"],
  sizes: ["siz1", "siz4"]
}
{
  _id: "zxcv",
  coll1Name: "John",
  types: ["typ2", "typ3"],
  sizes: ["siz1", "siz2"]
}
{
  _id: "fghj",
  coll1Name: "John",
  types: ["typ2", "typ3"],
  sizes: ["siz1", "siz4"]
}
我想使用聚合管道的
$lookup
阶段获取coll2中与coll1中具有相同类型+大小组合的所有文档。我知道这可以通过使用
$lookup pipeline
$expr
实现,但我似乎不知道如何动态地进行查询以传递到
$match
阶段

对于上述数据,我希望得到的输出是:

{
  _id: "qwer",
  coll1Name: "John",
  types: ["typ1", "typ3"],
  sizes: ["siz1", "siz4"]
}
{
  _id: "zxcv",
  coll1Name: "John",
  types: ["typ2", "typ3"],
  sizes: ["siz1", "siz2"]
}
您可以使用从
Col2
获取数据。然后需要检查
Col2
()中是否有与
Col1
匹配的元素。可以在这里使用。然后,您只需要使用


您使用管道字段过滤管道中的输入文档的方法是正确的 表达式通常应如下所示

"$expr": { 
    "$and": [
        { "$eq": [ "$name",  "$$coll1_name" ] },
        { "$setEquals": [ "$bags.type", "$$types" ] },
        { "$setEquals": [ "$bags.size", "$$sizes" ] }
    ]
}
其中,条件
{“$eq”:[“$name”,“$$coll1_name”]}
中的第一个匹配表达式检查
coll1
集合中的
name
字段是否与
coll2
输入文档中的
coll1Name
字段匹配。 当然,应该在管道中的变量中定义
coll2
中的字段,并使用
let
字段让管道访问这些字段

其他匹配过滤器基本上是检查数组是否相等,例如,
“$bags.type”
coll1
解析为
类型的数组,即
[“typ1”、“typ3”]

从恰巧是一个数组的获取输出字段时,您可以过滤该数组字段上
coll2
中的文档,其中可能有一些空列表作为上述管道$match过滤器的结果:

{ "$match": { "coll1Data.0": { "$exists": true } } }
总体而言,您的聚合管道操作如下所示:

db.getCollection('coll2').aggregate([
    { "$lookup" : {
        "from": "coll1",
        "let": { "coll1_name": "$coll1Name", "types": "$types", "sizes": "$sizes" },
        "pipeline": [
            { "$match": { 
                "$expr": { 
                    "$and": [
                        { "$eq": [ "$name",  "$$coll1_name" ] },
                        { "$setEquals": [ "$bags.type", "$$types" ] },
                        { "$setEquals": [ "$bags.size", "$$sizes" ] }
                    ]
                }
            } }
        ],
        "as": "coll1Data"
    } },
    { "$match": { "coll1Data.0": { "$exists": true } } },
    { "$project": { "coll1Data": 0 } }
])

谢谢你的信息!我正在尝试从coll1中查找coll2,不用担心。查找实际上是双向的,但上述管道的输出与预期/期望的匹配,当然,除非您想在
coll1
中进行一些预先筛选,也可以在
$lookup
管道中进行筛选。谢谢!这是一个很好的解决方案,尽管不是最有效的。我试图只获取所需的文档,而不是获取超过所需的文档,然后对其进行过滤。