Возвращает конкретное поле значения массива в совокупности - PullRequest
0 голосов
/ 24 августа 2018

У меня проблема в MongoDB. Я пытаюсь создать очень сложный агрегатный запрос, и он работает почти так, как я хочу, но у меня все еще есть тройки, и проблема в том, что мне нужно переместить специальное поле, чтобы я мог используйте его позже.

Мой агрегат сейчас выглядит так.

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 голосов
/ 24 августа 2018

Вы можете отфильтровать элемент из массива, где существует поле primary, используя $filter агрегацию, а затем легко $group с полем media._id и получите значение документа $first.

Наконец ваш запрос будет

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