Spring Data, MongoDB. How to get nested object (non-document) from document's array

Viewed 1668

Mongo document 'History':

@Document(collection = "histories")
@Data
public class History {
    @Id
    private String id;

    @Transient
    private final String name = MAIN_FOLDER;
    private String appleId;
    private ArrayList<Item> historyItems = new ArrayList<>();
    private ArrayList<Folder> historyFolders = new ArrayList<>();
}

Model of Folder:

@Data
public class Folder {
    private String name;
    private LocalDateTime date;
    private ArrayList<Item> historyItem = new ArrayList<>();
}

Query with Criteria:

    public Folder findFolderByName(final String name) {
        Query query = new Query();
        query.addCriteria(Criteria.where("historyFolders.name").is(name));
        return template.findOne(query, Folder.class);
    }

I got Null from this query. Sorry, I am new to this technologies, I did'nt find info about Criterias for documented arrays.

1 Answers

You are executing the Query at the wrong collection. Folder is not the collection but only a nested document in the "histories" collection.

And also: you cannot just return the nested document with 'classic' query execution. You have to filter it on the client side (your java code), use projections $elemMatch filter and unwind on client-side or use aggregation pipelines for this. Look at this Question: there are a lot of solutions if you need this in a query/pipeline.

Your query looks correct. You only have to update your query execution to use the History Entity instead of the Folder entity.

public History findFolderByName(final String name) {
    Query query = new Query();
    query.addCriteria(Criteria.where("historyFolders.name").is(name));
    return template.findOne(query, History.class);
}

If you use this query often and there a lot of documents in your collection: think about creating an index on historyFolders.name

Related