Requisitos del escenario
El requisito es actualizar parcialmente el documento mongo. Para consultar el documento completo es necesario recorrerlo para encontrar la actualización. El código es muy desagradable. Quiero usar la consulta mongo para encontrar directamente la parte modificada y realizar una actualización parcial de la modificación.
estructura de datos
{
"_id": ObjectId("..."),
"name": "Alice",
"addresses": [
{
"type": "home",
"locations": [
{
"city": "New York", "street": "123 Main St" },
{
"city": "Los Angeles", "street": "456 Elm St" }
]
},
{
"type": "work",
"locations": [
{
"city": "Chicago", "street": "789 Oak St" },
{
"city": "San Francisco", "street": "987 Maple St" }
]
}
]
}
el código
consultar documentos anidados
public List<String> findStreetNamesWithKeyword(String id,String city) {
//封装对象列表查询条件
List<AggregationOperation> commonOperations = new ArrayList<>();
//1. 指定查询主文档
MatchOperation match = Aggregation.match(Criteria.where("_id").is(new ObjectId(id)));
commonOperations.add(match);
//2. 拆分内嵌文档
UnwindOperation unwind = Aggregation.unwind("addresses");
commonOperations.add(unwind);
UnwindOperation unwind1 = Aggregation.unwind("addresses.locations");
commonOperations.add(unwind1);
//3. 指定查询子文档
MatchOperation match2 = Aggregation.match(
Criteria.where("addresses.locations.ctiy").is(city));
commonOperations.add(match2);
//4. 指定投影,返回哪些字段(映射到嵌套类的关键是,把相关字段展示出来)
ProjectionOperation project = Aggregation.project().and("addresses.locations.ctiy").as("city").and("addresses.locations.street").as("street");
commonOperations.add(project);
//创建管道查询对象
Aggregation aggregation = Aggregation.newAggregation(commonOperations);
AggregationResults<Location> reminds = mongoTemplate
.aggregate(aggregation, "集合名称", Location.class);
List<Location> mappedResults = reminds.getMappedResults();
System.out.println("######result:" + mappedResults );
}
Actualizar parcialmente documentos anidados
@Service
public class PersonService {
private final MongoTemplate mongoTemplate;
@Autowired
public PersonService(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
public void updateNestedArray(String personName, String city, Location newLocation) {
Query query = new Query(Criteria.where("name").is(personName)
.and("addresses.type").is(addressType));
Update update = new Update().set("addresses.$[].locations.$[elem]", newLocation);
update.filterArray(Criteria.where("elem.city").is(city));
mongoTemplate.updateFirst(query, update, "persons");
}
}