在 MongoDB for Spring 中查找和更新嵌套列表项(如
@DBRef
)的最佳方法是什么?
我有一个AppliedApplication类:
@Document(collection = "applied_application")
public class AppliedApplication {
@Id
private String id;
@Field("program")
@DBRef
private List<Program> programList;
// getters and setters
}
将 Program 类设置为
@DBRef
:
@Document(collection = "program")
public class Program {
@Id
private String id;
@Field("program_name")
private String programName;
// getters and setters
}
我正在寻找一种使用以下查询查找和更新嵌套列表项的方法:
用于通过 It's Id 从 AppliedApplication 集合中查找 Program 对象的查询:
Query query = new Query();
query.addCriteria(Criteria.where("id").is(applicationId)
.and("program.$id").is(new ObjectId(programId)));
Program program = mongoTemplate.findOne(query, Program.class);
用于从 AppliedApplication 中删除列表项的查询:
Update update = new Update().pull("program", new BasicDBObject("program.$id", new ObjectId(programId)));
mongoTemplate.updateMulti(new Query(), update, AppliedApplication.class);
他们都不起作用,我完全不知道。
查找:
使用
positional operator
/$elemMatch
在 AppliedApplication 中查找匹配的程序 DBRef。
$positional
投影
Query query = new Query();
query.addCriteria(Criteria.where("id").is(new ObjectId(applicationId)).and("program.$id").is(new ObjectId(programId)));
query.fields().position("program", 1);
AppliedApplication application = mongoTemplate.findOne(query, AppliedApplication.class);
Program program = application.getProgramList().get(0);
$elemMatch
投影
Query query = new Query();
query.addCriteria(Criteria.where("id").is(new ObjectId(applicationId)));
query.fields().elemMatch("program", Criteria.where("$id").is(new ObjectId(programId)));
AppliedApplication application = mongoTemplate.findOne(query, AppliedApplication.class);
Program program = application.getProgramList().get(0);
删除:
使用
$pull
从程序 DBref 列表中删除 DBRef。
Query query = Query.query(Criteria.where("$id").is(new ObjectId(programId)));
Update update = new Update().pull("program", query);
mongoTemplate.updateMulti(new Query(), update, AppliedApplication.class);
添加
使用
$push
将新程序添加到列表中。
Query query = new Query();
query.addCriteria(Criteria.where("id").is(new ObjectId(applicationId)));
Update update = new Update().push("program", new DBRef("program", new ObjectId(programId));
mongoTemplate.updateMulti(query, update, AppliedApplication.class);
如果您返回 AppliedApplication,第一个查询将运行
Query query = new Query();
query.addCriteria(Criteria.where("id")
.is(new ObjectId(applicationId))
.and("program.$id")
.is(new ObjectId(programId)));
AppliedApplication application = this.mongoOperations.findOne(query, AppliedApplication .class);
然后使用application对象来获取程序。
对于第二个查询,您需要更改,
Update update = new Update().pull("program", new BasicDBObject("$id", new ObjectId(programId)));
mongoTemplate.updateMulti(new Query(), update, AppliedApplication.class);
将 --> abc.$id 替换为 $id
我有类似的问题,我在
MongoRepository
界面中使用 @Query
注释和 @Update
注释解决了它。
我有一个
accounts
集合,每个帐户都有一个角色列表(每个角色都是对roles
集合的引用)。我想从 roles
集合中删除角色,并从拥有该角色的所有账户中删除该角色引用。
@Document(collection = "roles")
class Role {
@Id
private String id;
private String name;
}
@Document(collection = "accounts")
class Account {
@Id
private String id;
@DBRef
private List<Role> roles;
}
@Repository
public interface AccountRepository extends MongoRepository<Account, String> {
/**
* Remove a specific role from all accounts.
*/
@Query("{ 'roles.$id': { $oid: ?0 } }")
@Update("{ $pull: { roles: { $id: { $oid: ?0 } } } }")
void removeRoleFromAllAccounts(String roleId);
}
@Query
注释定义了选择要更新的文档的查询。 @Update
注释定义适用于所选文档的更新操作。查询和更新操作中的?0
占位符指的是第一个方法参数(roleId
)。在查询和更新操作中使用 $oid
是匹配角色引用的 ObjectId
表示所必需的。
注意:如果您使用
@DocumentReference
注解而不是 @DBRef
注解,则应使用以下查询和更新操作,因为引用的底层表示不同。如果您自定义了参考表示,您可能需要调整查询和更新操作。
@Repository
public interface AccountRepository extends MongoRepository<Account, String> {
/**
* Remove a specific role from all accounts.
*/
@Query("{ roles: { $oid: ?0 } }")
@Update(value = "{ $pull: { roles: { $oid: ?0 } } }")
void removeRoleFromAllAccounts(String roleId);
}