统计文件MongoDB java

时间:2017-04-21 13:19:28

标签: java mongodb mongodb-java

我是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"}

此致

2 个答案:

答案 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
}