Search code examples
mongodbmongodb-queryaggregation-frameworkmongo-javamongo-java-driver

How to aggregate values in an array of objects in MongoDB


I store documents from cars and want to get the temperature of all Mercedes cars as an array, how should the query be in Mongodb?

 { "_id" : { "$oid" : "5880ff305d15f416c89457b7" },
     "car" : "mercedes",
      "engine" : { 
            "sensor" : {
                        "temperatur" : "20",
                        "speed" : "100", 
                        "hue" : "40" 
                        }
                },
         "motor" : {
                    "Power" : "155", 
                    "Topspeed" : "400" 
                    } 
}

{ "_id" : { "$oid" : "5880ff305d15f416c89457b7" },
     "car" : "mercedes",
      "engine" : { 
            "sensor" : {
                        "temperatur" : "50",
                        "speed" : "100", 
                        "hue" : "40" 
                        }
                },
         "motor" : {
                    "Power" : "155", 
                    "Topspeed" : "400" 
                    } 
}

I would like to select the temperature for all Mercedes cars and receive it. result should be like [20,50]

EDIT: My code lookls like the following iam using JAVA:

  MongoClient mongoClient = new MongoClient();
      MongoDatabase database = mongoClient.getDatabase("test");
      MongoCollection<Document> coll = database.getCollection("myTestCollection");

Solution

  • You can try something like this with regular query if you're okay with distinct values.

    db.cars.distinct("engine.sensor.temperatur", {"car" : "mercedes"});
    

    This will give you

    [ "20", "50" ]
    

    Update - Java equivalent:

    List<String> temps = coll.distinct("engine.sensor.temperatur", new Document("car", "mercedes"), String.class).into(new ArrayList<>());
    

    Update - Aggregation Option

    Bson match = new Document("$match", new Document("car", "mercedes"));
    
    Bson group = new Document("$group", new Document("_id", "$car").append("temps", new Document("$push", "$engine.sensor.temperatur")));
    
    List<String> temps  = (List<String>) coll.aggregate(Arrays.asList(match, group)).map(document -> document.get("temps")).first();