【问题标题】:process/query multiple subdocuments in mongodb with Java driver使用 Java 驱动程序在 mongodb 中处理/查询多个子文档
【发布时间】:2018-11-29 19:05:26
【问题描述】:

我有类似的文件

{
"_id" : ObjectId("5bfdb66f0f77e33b90f53fad"),
"email" : "amit@gmail.com",
"appointments" : [
    {
        "year" : "2018",
        "months" : "12",
        "day" : "31",
        "hour" : "10",
        "minute" : "30",
        "doctorsName" : "Doc 1",
        "hospitalName" : "Place 1",
        "sortOrder" : "201812311030"
    },
    {
        "year" : "2018",
        "months" : "09",
        "day" : "31",
        "hour" : "10",
        "minute" : "30",
        "doctorsName" : "Doc 1",
        "hospitalName" : "Place 1",
        "sortOrder" : "201809311030"
    },
    {
        "year" : "2018",
        "months" : "11",
        "day" : "30",
        "hour" : "05",
        "minute" : "30",
        "doctorsName" : "Doc 1",
        "hospitalName" : "Place 1",
        "sortOrder" : "201811300530"
    }
],
"medicalData" : [
    {
        "year" : "2018",
        "months" : "09",
        "day" : "31",
        "symptomsList" : [“headache”,“nausea”,"cough"],
        "weight" : "70",
        "bloodPressureSystolic" : "120",
        "bloodPressureDiastolic" : "80",
        "medications" : [“med 1”,“med 2”],
        "sortOrder" : "20180931"
    },
    {
        "year" : "2018",
        "months" : "10",
        "day" : "31",
        "symptomsList" : [“headache”,"cough","Vomiting","Body Pain"],
        "weight" : "70",
        "bloodPressureSystolic" : "120",
        "bloodPressureDiastolic" : "80",
        "medications" : [“med 1”,“med 2”,"med 3"],
        "sortOrder" : "20181031"
    }
]
}

我想根据不同的参数处理两个子文档。在聚合器的帮助下,我尝试了。但是没能成功。

我希望包含所有文件和约会数据的数据应该大于某个排序顺序(order1)和医疗数据等于另一个排序顺序(order2)值。对于该特定排序顺序,只有一个医疗数据可用。现在我正在编写两个查询,一个用于约会,另一个用于医疗数据,并将它们合并为一个完整的 JSON。

我想要的输出类型是:

{
   "email" : "amit@gmail.com",
   “appointments”:
          [{
                “year”:2018,
                “month”:8,
                “day”:1,
                “hour”:7,
                “minutes”:6,
                “doctorName”:”Doc 1”,
                “hospitalName”:”Place 1”
            },
            {
                “year”:2018,
                “month”:10,
                “day”:15,
                “hour”:11,
                “minutes”:16,
                “doctorName”:”Doc 1”,
                “hospitalName”:”Place 1”
             }],
   “symptoms”: [“headache”,“nausea”],
   “bloodPressureSystolic”:120,
   “bloodPressureDiastolic”:80,
   “weight”: 58.5,
   “medications”:[“med 1”,“med 2”]
   }

请忽略预期结果中的数据不匹配。

【问题讨论】:

    标签: mongodb mongodb-query aggregation-framework mongodb-java


    【解决方案1】:

    感谢@Senthur Deva,这就是我在 Java 中实现的方式

        DBObject filterAppointment = new BasicDBObject();
        filterAppointment.put("input", "$appointments");
        filterAppointment.put("as", "apnmt");
        filterAppointment.put("cond", new BasicDBObject("$gt", Arrays.<Object>asList("$$apnmt.sortOrder", sortOrder1)));
    
        BasicDBObject projectionAppointment = new BasicDBObject("$filter", filterAppointment);
    
        DBObject filterMedData = new BasicDBObject();
        filterMedData.put("input", "$medicalData");
        filterMedData.put("as", "med");
        filterMedData.put("cond", new BasicDBObject("$eq", Arrays.<Object>asList("$$med.sortOrder", sortOrder)));
    
        BasicDBObject projectionMedData = new BasicDBObject("$filter", filterMedData);
    
        AggregateIterable<Document> findIterable = usersCollection.aggregate(
                Arrays.asList(
                        new Document("$match", new Document("_id",new ObjectId(userId))),
                        new Document("$project",new Document("email",1)
                                    .append("appointments", projectionAppointment)
                                    .append("medicalData", projectionMedData)),
                        new Document("$addFields",new Document("medicalData",new Document("$arrayElemAt", Arrays.asList("$medicalData", 0)))),
                        new Document("$project",new Document("email",1)
                                    .append("appointments", 1)
                                    .append("year", "$medicalData.year")
                                    .append("months", "$medicalData.months")
                                    .append("day", "$medicalData.day")
                                    .append("symptomsList", "$medicalData.symptomsList")
                                    .append("weight", "$medicalData.weight")
                                    .append("bloodPressureSystolic", "$medicalData.bloodPressureSystolic")
                                    .append("bloodPressureDiastolic", "$medicalData.bloodPressureDiastolic")
                                    .append("medications", "$medicalData.medications")
                                    .append("sortOrder", "$medicalData.sortOrder"))
    
                    )   
            );
    

    【讨论】:

    • 附加修改:如果要为投影放置默认数据,请尝试如下:Document medYearDoc = new Document("$ifNull",Arrays.asList("$medicalData.year", "")); 并在项目查询中使用:.append(DBConstants.MedicalDataYearField, medYearDoc)
    【解决方案2】:

    试试这个Mongo Playground

    db.col.aggregate([
        {
            "$project": {
                "email": 1,
                "appointments": {
                    "$filter": {
                        "input": "$appointments",
                        "as": "apnmt",
                        "cond": {
                            "$gt": ["$$apnmt.sortOrder", "201811300530"]
                        }
                    }
                },
                "medicalData": {
                    "$filter": {
                        "input": "$medicalData",
                        "as": "med",
                        "cond": { "$eq": ["$$med.sortOrder", "20180931"] }
                    }
                }
            }
        },
        {
            "$addFields": {
                "medicalData": { "$arrayElemAt": ["$medicalData", 0] }
            }
        },
        {
            "$project": {
                "email": 1,
                "appointments": 1,
                "year": "$medicalData.year",
                "months": "$medicalData.months",
                "day": "$medicalData.day",
                "symptomsList": "$medicalData.symptomsList",
                "weight": "$medicalData.weight",
                "bloodPressureSystolic": "$medicalData.bloodPressureSystolic",
                "bloodPressureDiastolic": "$medicalData.bloodPressureDiastolic",
                "medications": "$medicalData.medications",
                "sortOrder": "$medicalData.sortOrder"
            }
        }
    ])
    

    【讨论】:

    • 感谢您的询问。还要感谢 MongoPlayground。我可以在这里测试我的查询。我想要在 Java 中实现所有这些。但无论如何,这是一个很大的帮助,因为我找到了方向。
    猜你喜欢
    • 2011-11-16
    • 2012-11-02
    • 1970-01-01
    • 2012-04-05
    • 1970-01-01
    • 2012-05-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多