0

I want to retrieve an array from MongoDB using Spring Data Mongo.

I have collection consists of users with todos:

{
    "_id" : ObjectId("584d863e439e512f4c457eea"),
    "username" : "e",
    "todos" : [
        {
            "_id" : ObjectId("584d8654439e512f4c457eeb"),
            "title" : "Officiis id sed aut molestiae id id magni.",
            "body" : "Fugit velit rem incidunt. Et ad aliquam inventore voluptatem sed omnis voluptas. Aut sint eum voluptatem.",
            "when" : ISODate("1972-09-15T04:24:08.880Z"),
            "priority" : "HIGH",
            "status" : "DEFAULT",
            "tags" : [
                "animi",
                "veniam",
                "exercitationem"
            ]
        },
        // ...
    ]
}

I have tried the following:

public List<Todo> getUserTodos(String userId)
    Query x = new Query(Criteria.where("_id").is(userId));
    x.fields().exclude("_id").include("todos");
    return mongoTemplate.find(x, Todo.class);
}

Actually, I am getting an empty ArrayList. The response in mongo cli is like:

{
    "todos": [ {/* todo1 */}, {/* todo2 */} ]
}

How to return array from MongoDB or how to unwrap it for deserializing in Java?

2
  • What error did you get ? Just fyi the _id in the query is different from what shown in the sample. Commented Jan 7, 2017 at 19:09
  • @SagarReddy oops, my bad. Actually I am passing userId parameter there. I will fix question. Commented Jan 7, 2017 at 19:12

1 Answer 1

1

Well it would always return the document and not just a part of the document, when you include the field "todo" you just ensure that, that field is returned and others aren't but still it is the document which will be returned which will contain value "todos".

If you pass Todo.class it will look into a collection called todo, which isn't there, hence the empty list.

public List<Todo> getUserTodos(String userId)
    Query x = new Query(Criteria.where("_id").is(userId));
    x.fields().exclude("_id").include("todos");
    User user = mongoTemplate.findOne(x, User.class);
    return user.getTodos();
}

This same thing can be done with a map

public List<Todo> getUserTodos(String userId)
    Query x = new Query(Criteria.where("_id").is(userId));
    x.fields().exclude("_id").include("todos");
    Map user = mongoTemplate.findOne(x, Map.class);
    if(user != null && user.containsKey("todos")){
      return (List<Todo>)user.get("todos");
    }
    return null;
}
Sign up to request clarification or add additional context in comments.

2 Comments

Yes, I tried first workaround. What about performance of such query?
As far as I can see it is really optimized, look at the facts, you are querying against _id which is primary key which is already indexed, you are including the field todos only, I understand it could have much data, but still it is as fast as it gets.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.