返回聚合中的特定数组值字段

时间:2018-08-24 17:52:13

标签: mongodb aggregation-framework aggregate

我在MongoDB中遇到问题,我正在尝试建立一个非常复杂的聚合查询,并且它的工作几乎是我想要的,但是我仍然遇到麻烦,而问题是我需要移动一个spefiect字段,这样我才能以后使用。

我的汇总现在看起来像这样。

db.getCollection('travel_sights').aggregate([{
  '$match': {
    'preview.photo' : {
      '$exists':true
    },
    '_id': {
      '$in' : [ObjectId("5b7af9701fbad410e10f32f7")]
    }
  }
},{
  '$unwind' : '$preview.photo'
}, {
  '$lookup':{
    'from' : 'media_data',
    'localField' : '_id',
    'foreignField':'bind',
    'as':'media'
  }   
}])

,它将返回这样的数据。

{
    "_id" : ObjectId("5b7af9701fbad410e10f32f7"),
    "preview" : {
        "photo" : {
            "id" : ObjectId("5b7affea1fbad441494a663b"),
            "sort" : 0
        }
    },
    "media" : [ 
        {
            "_id" : ObjectId("5b7affea1fbad441494a663b")
        }, 
        {
            "_id" : ObjectId("5b7b002d1fbad441494a663c")
        }, 
        {
            "_id" : ObjectId("5b7b00351fbad441494a663d")
        }, 
        {
            "_id" : ObjectId("5b7d9baa1fbad410de638bbb")
        }, 
        {
            "_id" : ObjectId("5b7d9bae1fbad410e10f32f9")
        }, 
        {
            "_id" : ObjectId("5b7d9bb11fbad441494a663e")
        }, 
        {
            "_id" : ObjectId("5b7d9bb41fbad4ff97273402")
        }, 
        {
            "_id" : ObjectId("5b7d9bb71fbad4ff99527e82")
        }, 
        {
            "_id" : ObjectId("5b7d9bbb1fbad410de638bbc")
        }, 
        {
            "_id" : ObjectId("5b7d9bbe1fbad410e10f32fa")
        }, 
        {
            "_id" : ObjectId("5b7d9bc11fbad441494a663f")
        }, 
        {
            "_id" : ObjectId("5b7d9bc41fbad4ff97273403")
        }, 
        {
            "_id" : ObjectId("5b7d9bc71fbad4ff99527e83")
        }, 
        {
            "_id" : ObjectId("5b7d9bca1fbad410de638bbd")
        }, 
        {
            "_id" : ObjectId("5b7d9bcd1fbad441494a6640")
        }, 
        {
            "_id" : ObjectId("5b7d9bd01fbad4ff97273404")
        }
    ]
}
{
    "_id" : ObjectId("5b7af9701fbad410e10f32f7"),
    "preview" : {
        "photo" : {
            "id" : ObjectId("5b7b002d1fbad441494a663c"),
            "sort" : 0
        }
    },
    "media" : [ 
        {
            "_id" : ObjectId("5b7affea1fbad441494a663b")
        }, 
        {
            "_id" : ObjectId("5b7b002d1fbad441494a663c")
        }, 
        {
            "_id" : ObjectId("5b7b00351fbad441494a663d")
        }, 
        {
            "_id" : ObjectId("5b7d9baa1fbad410de638bbb")
        }, 
        {
            "_id" : ObjectId("5b7d9bae1fbad410e10f32f9")
        }, 
        {
            "_id" : ObjectId("5b7d9bb11fbad441494a663e")
        }, 
        {
            "_id" : ObjectId("5b7d9bb41fbad4ff97273402")
        }, 
        {
            "_id" : ObjectId("5b7d9bb71fbad4ff99527e82")
        }, 
        {
            "_id" : ObjectId("5b7d9bbb1fbad410de638bbc")
        }, 
        {
            "_id" : ObjectId("5b7d9bbe1fbad410e10f32fa")
        }, 
        {
            "_id" : ObjectId("5b7d9bc11fbad441494a663f")
        }, 
        {
            "_id" : ObjectId("5b7d9bc41fbad4ff97273403")
        }, 
        {
            "_id" : ObjectId("5b7d9bc71fbad4ff99527e83")
        }, 
        {
            "_id" : ObjectId("5b7d9bca1fbad410de638bbd")
        }, 
        {
            "_id" : ObjectId("5b7d9bcd1fbad441494a6640")
        }, 
        {
            "_id" : ObjectId("5b7d9bd01fbad4ff97273404")
        }
    ]
}
{
    "_id" : ObjectId("5b7af9701fbad410e10f32f7"),
    "preview" : {
        "photo" : {
            "id" : ObjectId("5b7b00351fbad441494a663d"),
            "sort" : 0,
            "primary" : false
        }
    },
    "media" : [ 
        {
            "_id" : ObjectId("5b7affea1fbad441494a663b")
        }, 
        {
            "_id" : ObjectId("5b7b002d1fbad441494a663c")
        }, 
        {
            "_id" : ObjectId("5b7b00351fbad441494a663d")
        }, 
        {
            "_id" : ObjectId("5b7d9baa1fbad410de638bbb")
        }, 
        {
            "_id" : ObjectId("5b7d9bae1fbad410e10f32f9")
        }, 
        {
            "_id" : ObjectId("5b7d9bb11fbad441494a663e")
        }, 
        {
            "_id" : ObjectId("5b7d9bb41fbad4ff97273402")
        }, 
        {
            "_id" : ObjectId("5b7d9bb71fbad4ff99527e82")
        }, 
        {
            "_id" : ObjectId("5b7d9bbb1fbad410de638bbc")
        }, 
        {
            "_id" : ObjectId("5b7d9bbe1fbad410e10f32fa")
        }, 
        {
            "_id" : ObjectId("5b7d9bc11fbad441494a663f")
        }, 
        {
            "_id" : ObjectId("5b7d9bc41fbad4ff97273403")
        }, 
        {
            "_id" : ObjectId("5b7d9bc71fbad4ff99527e83")
        }, 
        {
            "_id" : ObjectId("5b7d9bca1fbad410de638bbd")
        }, 
        {
            "_id" : ObjectId("5b7d9bcd1fbad441494a6640")
        }, 
        {
            "_id" : ObjectId("5b7d9bd01fbad4ff97273404")
        }
    ]
}

以及您可以处理的最后数据上面有preview.photo.primary,并且在完成汇总查询后,我想返回该字段。

我的最终查询如下:

db.getCollection('travel_sights').aggregate([{
  '$match': {
    'preview.photo' : {
      '$exists':true
    },
    '_id': {
      '$in' : [ObjectId("5b7af9701fbad410e10f32f7")]
    }
  }
},{
  '$unwind' : '$preview.photo'
}, {
  '$lookup':{
    'from' : 'media_data',
    'localField' : '_id',
    'foreignField':'bind',
    'as':'media'
  }   
},{
  '$unwind':'$media'
},{
  '$project' : {
    'preview' : 1,
    'media': 1,
  }
}, {
  '$group': {
    '_id':'$media._id',
    'primary': {
      '$first':'$preview'
    }
  }   
}])

这里的问题是当我想返回$preview以便我可以找到它的主数据库时,它总是只返回不存在该值的第一个,如果我使用$push,问题是我得到了每件事。

有没有一种方法可以让我选择合适的主要价值?尝试$addFields来阻止锁定。

旅游景点数据:

{
    "_id" : ObjectId("5b7af9701fbad410e10f32f7"),
    "city_id" : ObjectId("5b6d0cb6222d4c70b803eaeb"),
    "activated" : true,
    "deleted" : false,
    "url" : "url is here",
    "name" : "title of it here",
    "updated_at" : ISODate("2018-08-22T17:22:27.000Z"),
    "content" : "content here",
    "preview" : {
        "photo" : [ 
            {
                "id" : ObjectId("5b7affea1fbad441494a663b"),
                "sort" : 0
            }, 
            {
                "id" : ObjectId("5b7b002d1fbad441494a663c"),
                "sort" : 0
            }, 
            {
                "id" : ObjectId("5b7b00351fbad441494a663d"),
                "sort" : 0,
                "primary" : true
            }, 
            {
                "id" : ObjectId("5b7d9baa1fbad410de638bbb"),
                "sort" : 0
            }, 
            {
                "id" : ObjectId("5b7d9bae1fbad410e10f32f9"),
                "sort" : 0
            }, 
            {
                "id" : ObjectId("5b7d9bb11fbad441494a663e"),
                "sort" : 0
            }, 
            {
                "id" : ObjectId("5b7d9bb41fbad4ff97273402"),
                "sort" : 0,
                "primary" : false
            }, 
            {
                "id" : ObjectId("5b7d9bb71fbad4ff99527e82"),
                "sort" : 0,
                "primary" : false
            }, 
            {
                "id" : ObjectId("5b7d9bbb1fbad410de638bbc"),
                "sort" : 0
            }, 
            {
                "id" : ObjectId("5b7d9bbe1fbad410e10f32fa"),
                "sort" : 0
            }, 
            {
                "id" : ObjectId("5b7d9bc11fbad441494a663f"),
                "sort" : 0
            }, 
            {
                "id" : ObjectId("5b7d9bc41fbad4ff97273403"),
                "sort" : 0,
                "primary" : false
            }, 
            {
                "id" : ObjectId("5b7d9bc71fbad4ff99527e83"),
                "sort" : 0,
                "primary" : false
            }, 
            {
                "id" : ObjectId("5b7d9bca1fbad410de638bbd"),
                "sort" : 0,
                "primary" : false
            }, 
            {
                "id" : ObjectId("5b7d9bcd1fbad441494a6640"),
                "sort" : 0,
                "primary" : false
            }, 
            {
                "id" : ObjectId("5b7d9bd01fbad4ff97273404"),
                "sort" : 0
            }
        ]
    }
}

此处有3个示例照片绑定数据:

{
    "_id" : ObjectId("5b7affea1fbad441494a663b"),
    "file-name" : "55575110311__0F115282-B5A0-4654-AA44-B7DC2C682992.jpeg",
    "options" : [ 
        ObjectId("5b6fb855222d4c70b8041093")
    ],
    "type" : "images",
    "files" : [ 
        {
            "width" : 70,
            "height" : 53
        }, 
        {
            "width" : 400,
            "height" : 300
        }, 
        {
            "width" : 800,
            "height" : 600
        }, 
        {
            "width" : 1600,
            "height" : 1200
        }
    ],
    "bind" : [ 
        ObjectId("5b7af9701fbad410e10f32f7")
    ]
}
{
    "_id" : ObjectId("5b7b002d1fbad441494a663c"),
    "file-name" : "55575110748__E7B07EFD-9F7E-40D6-8B57-38F708E4C0C0.jpeg",
    "options" : [ 
        ObjectId("5b6fb855222d4c70b8041093")
    ],
    "type" : "images",
    "files" : [ 
        {
            "width" : 70,
            "height" : 53
        }, 
        {
            "width" : 400,
            "height" : 300
        }, 
        {
            "width" : 800,
            "height" : 600
        }, 
        {
            "width" : 1600,
            "height" : 1200
        }
    ],
    "bind" : [ 
        ObjectId("5b7af9701fbad410e10f32f7")
    ],
    "description" : "this is secoudn demo!",
    "title" : "demo 3"
}
{
    "_id" : ObjectId("5b7b00351fbad441494a663d"),
    "file-name" : "paris2.jpg",
    "options" : [ 
        ObjectId("5b6fb855222d4c70b8041093")
    ],
    "type" : "images",
    "files" : [ 
        {
            "width" : 70,
            "height" : 53
        }, 
        {
            "width" : 400,
            "height" : 300
        }, 
        {
            "width" : 800,
            "height" : 600
        }, 
        {
            "width" : 1600,
            "height" : 1200
        }
    ],
    "bind" : [ 
        ObjectId("5b7af9701fbad410e10f32f7")
    ],
    "description" : "this is a demo1 :)",
    "title" : "demo"
}

1 个答案:

答案 0 :(得分:1)

您可以使用$filter聚合从primary字段所在的数组中过滤出元素,然后使用media._id字段轻松$group并获取{{3 }}文档价值。

最后,您的查询将是

db.getCollection("travel_sights").aggregate([
  { "$match": {
    "preview.photo" : { "$exists":true },
    "_id": { "$in" : [ ObjectId("5b7af9701fbad410e10f32f7") ] }
  }},
  { "$addFields": {
    "preview.photo": {
      "$arrayElemAt": [
        { "$filter": {
          "input": "$preview.photo",
          "as": "photo",
          "cond": { "$ne": [ "$$photo.primary", undefined ] }
        }}, 0
      ]
    }
  }},
  { "$lookup":{
    "from" : "media_data",
    "localField" : "_id",
    "foreignField": "bind",
    "as": "media"
  }},
  { "$unwind":"$media" },
  { "$project" : { "preview" : 1, "media": 1, }},
  { "$group": {
    "_id": "$media._id",
    "primary": { "$first": "$preview" }
  }}  
])