在 MongoDB for Spring 中查找/删除 @DBref 列表项

问题描述 投票:0回答:3

在 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 IdAppliedApplication 集合中查找 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);

他们都不起作用,我完全不知道。

spring mongodb spring-mvc spring-boot mongodb-query
3个回答
4
投票

查找:

使用

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);

1
投票

如果您返回 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


0
投票

我有类似的问题,我在

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
表示所必需的。

参考:MongoDB特定的数据操作方法

注意:如果您使用

@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);
}
© www.soinside.com 2019 - 2024. All rights reserved.