我有两个域对象,
@Document
public class PracticeQuestion {
private int userId;
private List<Question> questions;
// Getters and setters
}
@Document
public class Question {
private int questionID;
private String type;
// Getters and setters
}
我的JSON文档是这样的,
{
"_id" : ObjectId("506d9c0ce4b005cb478c2e97"),
"userId" : 1,
"questions" : [
{
"questionID" : 1,
"type" : "optional"
},
{
"questionID" : 3,
"type" : "mandatory"
}
]
}
我必须根据UserID和QuestonID更新“type”,因此我在定制的Repository接口中编写了一个findBy查询方法,
public interface CustomRepository extends MongoRepository<PracticeQuestion, String> {
List<PracticeQuestion> findByUserIdAndQuestionsQuestionID(int userId,int questionID);
}
我的问题是,当我执行这个方法时,当UserID为1,QueskonID为3时,它返回整个问题列表,而不考虑QuesuonID。查询方法名称是否有效,或者我应该如何编写嵌套对象的查询。
谢谢你的建议。
4条答案
按热度按时间olqngx591#
只需在该方法上使用
@Query
注解。通过添加
@Query
注解的fields
部分,您告诉Mongo只返回文档的该部分。但请注意,它仍然以相同的格式返回整个文档-只是缺少您未指定的所有内容。因此,您的代码仍然必须返回List<PracticeQuestion>
,并且您必须这样做:6qfn3psc2#
属性表达式
属性表达式只能引用托管实体的直接属性,如上例所示。在创建查询时,您已经确保分析的属性是托管域类的属性。但是,您也可以通过遍历嵌套特性来定义约束。假设个人拥有带邮政编码的地址。在这种情况下,方法名为
List<Person> findByAddressZipCode(ZipCode zipCode);
将创建属性遍历x.Address.zipCode。解析算法首先将整个部分(AddressZipCode)解释为属性,并检查域类中具有该名称的属性(未大写)。如果算法成功,它将使用该属性。如果不是,该算法将 Camel 包部分的源代码从右侧拆分为头部和尾部,并尝试找到相应的属性,在我们的示例中为AddressZip和Code。如果算法找到具有该头部的属性,它将获取尾部,并继续从那里向下构建树,以刚才描述的方式拆分尾部。如果第一个拆分不匹配,则算法将拆分点向左移动(Address,ZipCode)并继续。虽然这在大多数情况下都应该有效,但算法可能会选择错误的属性。假设Person类也有一个AddressZip属性。该算法在第一轮拆分时就已经匹配,基本上选择了错误的属性,最终失败(因为AddressZip的类型可能没有code属性)。要解决这种歧义,您可以在方法名中使用_来手动定义遍历点。因此,我们的方法名称将以如下形式结束:
UserDataRepository:
ProfileRepository:
UserDataRepositoryImpl:
POJO示例:
对于您的存储库类中的上述文档/POJO:
userdata findByProfile_Email(字符串电子邮件);
参考:http://docs.spring.io/spring-data/data-commons/docs/1.6.1.RELEASE/reference/html/repositories.html
628mspwn3#
您需要使用Mongo聚合框架:
1)创建mongo仓库的自定义方法:Add custom method to Repository
2)需要创建一个类(因为展开操作改变了类结构),如下所示:
这将只给出那些与提供的
userId
和questionId
匹配的结果用户ID:1和问题ID:111的结果:
6yt4nkrj4#
我也有过类似的问题。为此,我在嵌套类属性之前添加了$。在下面尝试查询
@Query(value = "{ 'userId' : ?0, 'questions.$questionID' : ?1 }") List<PracticeQuestion> findPracticeQuestionByUserIdAndQuestionsQuestionID(int userId, int questionID);