我是MongoDB的新手,我发现计算嵌套文档的子编号相当复杂。
这是我的'users'
集合的一部分。
"_id" : ObjectId("58f9f7a91fb2bf7c46abe5d6"),
"name" : "fernando guima",
"premium" : true,
"email" : "lolol@loladamix.com",
"creationDate" : ISODate("2017-04-21T12:14:33.970Z"),
"playlists" : [
{
"name" : "minha Playlist",
"creationDate" : ISODate("2017-04-21T12:14:33.982Z"),
"videos" : [
{
"video_id" : "video1",
"creationDate" : ISODate("2017-04-21T13:00:38.461Z")
},
{
"video_id" : "video2",
"creationDate" : ISODate("2017-04-21T13:00:38.502Z")
}
]
},
{
"name" : "minha Playlist 2",
"creationDate" : ISODate("2017-04-21T12:14:33.983Z"),
"videos" : [ ]
}
]
}
我希望能够检索“播放列表”(播放列表中的孩子)中的“视频”数量并检索视频数据,我该怎么做?
我编写了以下代码,将video
添加到给定的playlist
:
public void addToPlaylist(String parameter, String value, String playListName, String video_id){
//user document
BasicDBObject query = new BasicDBObject(parameter, value);
//First it fetches the wanted document by a parameter and its value e.g, (name, Fernando)
BasicDBObject mObject = new BasicDBObject();
mObject.put("video_id", video_id);
mObject.put("creationDate", new Date());
BasicDBObject updateObj = new BasicDBObject();
//falta percorrer o array das playlists para encontrar o id pelo nome da playlist
updateObj.put("$push", new BasicDBObject("playlists."+"0"+".videos", mObject));
mMongo.getCollection("users").updateOne(query, updateObj);
}
我希望收到{videos : 2}
作为我第一个播放列表中的视频数量。还有一些关于视频数据的输出,例如:{"video_id" : "video1"}
此致
答案 0 :(得分:0)
您可以使用以下查询。查询将$match
选择文档,然后选择$unwind
playlists
数组,$project
到达videos
数组以计算其$size
并提取video_id
。
MongoClient client = new MongoClient("localhost", 27017);
MongoDatabase database = client.getDatabase("db");
MongoCollection<Document> collection = database
.getCollection("collection");
Bson filter = Filters.eq("_id", new ObjectId("58f9f7a91fb2bf7c46abe5d6"));
List<VideoResult> results = collection.aggregate(Arrays.asList(Aggregates.match(filter), Aggregates.unwind("$playlists"), Aggregates.project(Projections.fields(Arrays.asList(Projections.computed("videos", new Document("$size","$playlists.videos")),
Projections.computed("video_ids", "$playlists.videos.video_id")))))).map(VideoResult::new).into(new ArrayList<>());
输出:
{
"_id" : ObjectId("58f9f7a91fb2bf7c46abe5d6"),
"videos" : 2,
"video_ids" : [
"video1",
"video2"
]
}
{
"_id" : ObjectId("58f9f7a91fb2bf7c46abe5d6"),
"videos" : 0,
"video_ids" : [ ]
}
POJO的:
public class VideoResult {
private int videos;
private List<String> videoIds;
public VideoResult(Document doc) {
this.videos = doc.getInteger("videos");
this.videoIds = (List<String>) doc.get("video_ids");
}
// getters and setters
}
答案 1 :(得分:0)
另一个解决方案,MongoDB 3.4
db.users.aggregate([
{$unwind: '$playlists'}, {$addFields: {'playlists.id': '$_id'}},
{$replaceRoot: {newRoot: '$playlists'}},
{$unwind: {path: '$videos', preserveNullAndEmptyArrays: true}},
{$group: {_id: {name: '$name', creationDate: '$creationDate', _id: '$id'},
video_ids: {$push: '$videos.video_id'},
videos: {$sum: {$cond: [{$ifNull: ['$videos', 0]}, 1, 0]}}}},
{$addFields: {_id: '$_id._id'}}])
输出:
{
"_id" : ObjectId("58f9f7a91fb2bf7c46abe5d6"),
"video_ids" : [ ],
"videos" : 0
}
{
"_id" : ObjectId("58f9f7a91fb2bf7c46abe5d6"),
"video_ids" : [
"video1",
"video2"
],
"videos" : 2
}