Search code examples
springmongodbspring-mvcspring-bootspring-data-mongodb

Due to limitations of the com.mongodb.BasicDBObject exception when add multiple criteria GridFSDBFile query


I want add multiple criteria in GridFSDBFile, I have iterated the map and formed the criteria object but i am getting following exception

Due to limitations of the com.mongodb.BasicDBObject, you can't add a second '$and' expression specified.

My code snippet is

public void getFile(Map<String, Object> metaData) throws Exception {
    Criteria criteria = new Criteria();
    metaData.forEach((k, v) -> criteria.andOperator(Criteria.where("metadata." + k).is(v)));
    GridFSDBFile gridFSDBFile = gridFsOperations.findOne(new Query(criteria));
    if (gridFSDBFile == null) {
        throw new HttpConflictException();
}

Solution

  • You can update method to below. You are trying to provide multiple $and operator with each having a criteria.

    Btw, you don't need an explicit anding as mongodb provides implicit anding when criteria is separated by comma.

    public void getFile(Map<String, Object> metaData) throws Exception {
        Criteria criteria = new Criteria();
        metaData.forEach((k, v) -> criteria.and("metadata." + k).is(v));
        GridFSDBFile gridFSDBFile = gridFsOperations.findOne(new Query(criteria));
        if (gridFSDBFile == null) {
            throw new HttpConflictException();
    }
    

    In cases where you need explicit anding, you can use below code

    public void getFile(Map<String, Object> metaData) throws Exception {
        Criteria criteria = new Criteria();
        Criteria[] andExpressions = metaData.entrySet().stream().
                map(kv -> Criteria.where("data." + kv.getKey()).is(kv.getValue()))
                .toArray(Criteria[]::new);
        Query andQuery = new Query();
        Criteria andCriteria = new Criteria();
        andQuery.addCriteria(andCriteria.andOperator(andExpressions));
        GridFSDBFile gridFSDBFile = gridFsOperations.findOne(andQuery);
        if (gridFSDBFile == null) {
            throw new HttpConflictException();
    }