使用Java驱动程序在mongodb中处理/查询多个子文档

时间:2018-11-29 19:05:27

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

我有类似

的文档
{
"_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”]
   }

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

2 个答案:

答案 0 :(得分: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"))

                )   
        );

答案 1 :(得分:0)

尝试这个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"
        }
    }
])