【问题标题】:How to project fileName when we group with filePrefix in the Mongo aggregation当我们在 Mongo 聚合中使用 filePrefix 分组时如何投影文件名
【发布时间】:2017-03-24 04:10:07
【问题描述】:

目前我可以根据 filePrefix 进行分组,并使用 max fileId 获取记录。

在输出中,我可以获取 filePrefix 和 fileId,但无法获取 fileName 以及 filePrefix 和 fileId。

谁能帮我解决这个问题...

我的文件:

    {
            "_id" : ObjectId("58cbe224238b3953da3bc0bc"),
            "fileName" : "samplefile1_124.txt",
            "filePrefix":"samplefile1",
            "fileId":124
    }
    {
            "_id" : ObjectId("58cbe257238b3953da3bc0bd"),
            "fileName" : "samplefile2_125.txt",
            "filePrefix":"samplefile2",
            "fileId":125

    }
    {
            "_id" : ObjectId("58cf8d13f731b796bc343726"),
            "fileName" : "samplefile3_126.dat",
            "filePrefix":"samplefile3",
            "fileId":126
    }
    {
            "_id" : ObjectId("58cfa525f731b796bc343727"),
            "fileName" : "samplefile1_126.txt",
            "filePrefix":"samplefile1",
            "fileId":126
    }
    {
            "_id" : ObjectId("58cfa525f731b796bc343728"),
            "fileName" : "samplefile2_127.txt",
            "filePrefix":"samplefile2",
            "fileId":127

    }

我的代码:

    MongoClient mongo = new MongoClient("localhost",27017);
    MongoDatabase db = mongo.getDatabase("fileDB");
    MongoCollection<Document> col =  db.getCollection("fileStatus");

    List<String> docsList = new ArrayList<>();
    docsList.add("samplefile1");
    docsList.add("samplefile2");
    docsList.add("samplefile3");

    Set<String> docsSet = new HashSet<>();
    for(String st: docsList){
        docsSet.add(st);
        }

    Document match =  new Document("$match", new Document("filePrefix",new Document("$in",docsSet)));
    Document group =  new Document("$group" , new Document("_id","$filePrefix").append("fId", new Document("$max","$fileId")));
    Document project = new Document("$project",new Document("filePrefix","$_id").append("fileId", "$fId"));

     AggregateIterable<Document> output = col.aggregate(Arrays.asList(match,group,project));

        for (Document dbObject : output)
        {
            System.out.println(dbObject);
        }

我的输出:

文档{{_id=samplefile1, filePrefix=samplefile1, fileId=126.0}}
文档{{_id=samplefile2, filePrefix=samplefile2, fileId=127.0}}
文档{{_id=samplefile3, filePrefix=samplefile3, fileId=126.0}}

【问题讨论】:

  • 在小组赛中使用$first$last 和文件名。像.append("fileName", new Document("$first","$fileName") 这样的东西。如果要控制顺序,请在分组前使用排序阶段。
  • 我不想要第一个文件名。我需要在输出中显示最大 fileId 的文件名
  • 正如@Veeram 建议的那样,如果您将$sort 升序为fileId 作为第二个管道步骤,然后在您的$group 步骤中使用$last 以获取fileName,您将具有与最大 fileId 关联的文件名。

标签: java mongodb


【解决方案1】:

您需要运行以下聚合管道,该管道首先对文档进行排序,然后再应用组操作,因为您需要使用 $first(如果按降序排列)或 @如果您希望返回其他字段,请使用 987654322@(如果升序)运算符。这实质上将为您提供 max 字段以及相应的文档字段。

例如使用示例文档作为输入

db.test.aggregate([
    { "$match": { "filePrefix": { "$in": docsSet }  } },
    { "$sort": { "filePrefix": 1, "fileId": -1 } },
    { 
        "$group": {
            "_id": "$filePrefix",
            "fileId": { "$first": "$fileId"},
            "fileName": { "$first": "$fileName"}
        }
    }
])

即翻译为

Document match =  new Document(
    "$match", new Document("filePrefix",
        new Document("$in", docsSet)
    )
);
Document sort =  new Document("$sort", 
    new Document("filePrefix", 1).append("fileId", -1)
);
Document group =  new Document("$group" , 
    new Document("_id", "$filePrefix")
        .append("fileId",  new Document("$first", "$fileId")
        .append("fileName",  new Document("$first", "$fileName")
    )
);
Document project = new Document("$project",
    new Document("filePrefix", "$_id")
        .append("fileId", 1)
        .append("fileName", 1)
);

【讨论】:

  • 非常感谢。它帮助了我。
猜你喜欢
  • 2014-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-27
  • 2023-03-31
  • 1970-01-01
  • 2019-11-30
  • 1970-01-01
相关资源
最近更新 更多