Search code examples
javamongodbmongodb-java

Java-MongoDB Casting an array to a MongoCollection


I wonder if it is possible to re-search a document of a collection within an array, in MongoDB. Like this example:

JSON of Mongo

{
value1 : "aaa",
arrayvalue : [{
    value2 : "aaaaa",
    value3 : 1
    },{
    value2 : "aaaa",
    value3 : 2
    }]
}
{
value1 : "aaa",
arrayvalue : [{
    value2 : "bbbb",
    value3 : 3
    },{
    value2 : "bbbbb",
    value3 : 4
    }]
}

Java code

public static String getValue3(){
    MongoClient mongoClient = new MongoClient("localhost", 27017);
    MongoDatabase db = mongoClient.getDatabase("test2");
    MongoCollection<Document> collection = db.getCollection("test1");
    if(collection == null)
        return "";
    Document doc = collection.find(and(eq("value1", "aaa"), eq("arrayvalue.value2", "aaaa"))).first();
    if(doc != null){
        MongoCollection<Document> arrayv = (MongoCollection<Document>) doc.get("arrayvalue");
        Document newdoc = arrayv.find(eq("value2", "aaaa")).first();
        return newdoc.get("value3").toString();
    }
    return "";
}

Obviously this didn't work (the right result would be "2"). Can anyone help me to get this value3 number?


Solution

  • You can simplify your query to use $elemMatch projection.

    The below code collection.find(filter) with projection(elemMatch(filter)) returns the arrayvalue with single matching element for query and projection filter.

    doc.get("arrayvalue", List.class) to read the arrayvalue which will be [{value2 : "aaaa", value3 : 2}]

    arrayValue.get(0).get("value3") to read the value3.

    import static com.mongodb.client.model.Projections.elemMatch;
    
     public static String getValue3(){
          MongoClient mongoClient = new MongoClient("localhost", 27017);
          MongoDatabase db = mongoClient.getDatabase("test2");
          MongoCollection<Document> collection = db.getCollection("test1");
          if(collection == null)
            return "";
          Document doc = collection.find(eq("value1", "aaa")).projection(elemMatch("arrayvalue", eq("value2", "aaaa"))).first();
          if(doc != null) {
            List<Document> arrayValue = doc.get("arrayvalue", List.class);
            return arrayValue.get(0).get("value3").toString();
          }
          return "";
     }