Estoy haciendo una aplicación simple con Spring Boot (2.3.4) usando MongoDB con Spring Data para MongoDB. Por lo general, creo consultas para la aplicación usando la anotación @Query y funciona muy bien. Pero para una Agregación que quiero usar, construí una consulta con la clase Criterios. El criterio que necesito es como
where("primary").is(value).and("secondary").is("") .
Necesito todas las entradas donde el primario sea igual a 'valor' y el secundario esté vacío. La consulta ingresada en MOngoDB Compass
{ $and: [ { primary: 'value' }, { secondary: ''} ] }
funciona como se esperaba, pero cuando trato de usar Criteria con Spring, parece que la parte y la secundaria se descartan por completo. Obtengo resultados con 'valor' en primario y con cualquier cosa en secundario . Esto significa campos vacíos o cualquier otra cosa. Reemplazar la parte .is( .is("") con .regex("^$") no ayudó.
Esto me parece bastante básico, entonces, ¿qué me estoy perdiendo aquí? No quiero reemplazar el secundario vacío con una "bandera vacía", porque se siente mal.
Actualizar:
este es el codigo en cuestion
Criteria crit; if(!primary.equals(secondary)) { crit = where("primary").is(primary.name()).and("secondary").is(secondary.name()); } else { crit = where("primary").is(primary.name()).and("secondary").is(""); } MatchOperation matchStage = Aggregation.match(crit); GroupOperation groupStage = Aggregation.group("grouping").count().as("sum"); SortOperation sortStage = new SortOperation(Sort.by("_id")); Aggregation aggregation = Aggregation.newAggregation(matchStage, groupStage, sortStage); AggregationResults<TypePerGroup> results = mongoTemplate.aggregate(aggregation, "dataCollection", TypePerGroup.class);Esto funciona con mongodb: no estoy seguro de qué agrega la brújula de abstracción. Ambas consultas no generan la misma consulta json pero son iguales.
Consulta generada
where("primary").is(value).and("secondary").is("").es
{"primary":value, "secondary": ""}¿Quizás a la brújula no le gusta esta variante?
De todos modos, para generar una consulta similar a la que ingresó en la brújula, puede usar el siguiente código
Criteria criteria = new Criteria(); criteria.andOperator(Criteria.where("primary").is("hello"), Criteria.where("secondary").is("")); Query query = Query.query(criteria);Tu no te estas perdiendo nada. where("primary").is(value).and("secondary").is("") es correcto y es funcionalmente equivalente a { $and: [ { primary: 'value' }, { secondary: ''} ] } . Debe activar el registro de nivel de depuración para MongoTemplate para ver la consulta generada.
A se conectó a Atlas usando Mongo DBCompas y agregó 4 registros a la colección:
[{ "primary": "A", "secondary": "A" },{ "primary": "A", "secondary": "" },{ "primary": "B", "secondary": "B" },{ "primary": "B", "secondary": "" }]ambas consultas:
List<Data> firstResults = mongoTemplate.query(Data.class) .matching(Query.query(Criteria.where("primary").is("B").and("secondary").is(""))) .all(); System.out.println(firstResults); Criteria criteria = new Criteria(); criteria.andOperator(Criteria.where("primary").is("B"), Criteria.where("secondary").is("")); List<Data> secondResults = mongoTemplate.query(Data.class) .matching(Query.query(criteria)) .all(); System.out.println(secondResults);dio el mismo resultado:
[Data{primary='B', secondary=''}]Campfire, ¿puede proporcionar un ejemplo de su código para analizar?