스프링 데이터 - Mongodb - 내포된 객체에 대한 방법으로 찾기
두 개의 도메인 객체를 가지고 있습니다.
@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와 questionId를 기반으로 "type"을 업데이트해야 하므로 사용자 지정 Repository 인터페이스 내에 findBy 쿼리 방법을 작성했습니다.
public interface CustomRepository extends MongoRepository<PracticeQuestion, String> {
List<PracticeQuestion> findByUserIdAndQuestionsQuestionID(int userId,int questionID);
}
제 문제는 userId를 1로 하고 질문을 하면서 이 메서드를 실행할 때입니다.ID가 3인 경우, 질문과 상관없이 전체 질문 목록을 반환합니다.ID. 쿼리 메서드 이름이 유효한지 또는 중첩된 개체에 대한 쿼리를 작성하는 방법입니다.
제안해 주셔서 감사합니다.
사용하기만 하면 됩니다.@Query해당 메서드에 대한 주석입니다.
public interface CustomRepository extends MongoRepository<PracticeQuestion, String> {
@Query(value = "{ 'userId' : ?0, 'questions.questionID' : ?1 }", fields = "{ 'questions.questionID' : 1 }")
List<PracticeQuestion> findByUserIdAndQuestionsQuestionID(int userId, int questionID);
}
추가를 통해fields의 일부@Query주석, 당신은 Mongo에게 문서의 그 부분만 반환하라고 말하고 있습니다.그러나 지정하지 않은 모든 내용이 누락된 동일한 형식으로 전체 문서를 반환합니다.그래서 당신의 코드는 여전히 되돌아와야 합니다.List<PracticeQuestion>그리고 당신은 다음을 해야 할 것입니다.
foreach (PracticeQuestion pq : practiceQuestions) {
Question q = pq.getQuestions().get(0); // This should be your question.
}
속성 식
속성 표현식은 앞의 예와 같이 관리 엔티티의 직접 속성만 나타낼 수 있습니다.쿼리를 만들 때 이미 구문 분석된 속성이 관리 도메인 클래스의 속성인지 확인해야 합니다.그러나 중첩된 특성을 통과하여 제약 조건을 정의할 수도 있습니다.개인이 우편 번호가 있는 주소를 가지고 있다고 가정합니다.이 경우 메서드 이름:List<Person> findByAddressZipCode(ZipCode zipCode);traversal x.address.zipCode 속성을 생성합니다.확인 알고리즘은 전체 부품(AddressZipCode)을 속성으로 해석하는 것으로 시작하여 도메인 클래스에서 해당 이름(자본화되지 않음)의 속성을 확인합니다.알고리즘이 성공하면 해당 속성을 사용합니다.그렇지 않은 경우, 이 알고리즘은 낙타 케이스 부품의 소스를 오른쪽에서 머리와 꼬리로 분할하고 해당 속성(예: AddressZip 및 Code)을 찾습니다.알고리즘이 해당 머리를 가진 속성을 찾으면 꼬리를 사용하여 트리를 아래로 계속 구축하고 방금 설명한 방식으로 꼬리를 분할합니다.첫 번째 분할이 일치하지 않으면 알고리즘이 분할 지점을 왼쪽(주소, ZipCode)으로 이동하고 계속합니다.
대부분의 경우 이 방법이 사용 가능하지만 알고리즘이 잘못된 속성을 선택할 수 있습니다.사용자 클래스에도 addressZip 속성이 있다고 가정합니다.알고리즘이 첫 번째 분할 라운드에서 이미 일치하고 기본적으로 잘못된 속성을 선택하여 마지막으로 실패합니다(주소 유형 Zip에 코드 속성이 없을 수 있음).이 모호성을 해결하려면 메서드 이름 내부에 _를 사용하여 통과점을 수동으로 정의할 수 있습니다.그래서 우리의 메소드 이름은 다음과 같습니다.
사용자 데이터 리포지토리:
List<UserData> findByAddress_ZipCode(ZipCode zipCode);
UserData findByUserId(String userId);
프로필 리포지토리:
Profile findByProfileId(String profileId);
사용자 데이터 리포지토리 임플:
UserData userData = userDateRepository.findByUserId(userId);
Profile profile = profileRepository.findByProfileId(userData.getProfileId());
userData.setProfile(profile);
Pojo 표본:
public class UserData {
private String userId;
private String status;
private Address address;
private String profileId;
//New Property
private Profile profile;
//TODO:setter & getter
}
public class Profile {
private String email;
private String profileId;
}
리포지토리 클래스에 있는 위의 문서/POJO의 경우:
사용자 데이터 findByProfile_Email(문자열 전자 메일);
참고 자료: http://docs.spring.io/spring-data/data-commons/docs/1.6.1.RELEASE/reference/html/repositories.html
Mongo Aggregation 프레임워크를 사용해야 합니다.
mongo 리포지토리에 대한 사용자 정의 메서드 만들기 : 리포지토리에 사용자 정의 메서드 추가
UnwindOperation unwind = Aggregation.unwind("questions");
MatchOperation match = Aggregation.match(Criteria.where("userId").is(userId).and("questions.questionId").is(questionID));
Aggregation aggregation = Aggregation.newAggregation(unwind,match);
AggregationResults<PracticeQuestionUnwind> results = mongoOperations.aggregate(aggregation, "PracticeQuestion",
PracticeQuestionUnwind.class);
return results.getMappedResults();
다음과 같이 클래스를 생성해야 합니다(풀기 작업으로 인해 클래스 구조가 변경되었기 때문).
public class PracticeQuestionUnwind {
private String userId;
private Question questions;
제공된 됩니다.userId그리고.questionId
userId 1 및 questionId 111에 대한 결과:
{
"userId": "1",
"questions": {
"questionId": "111",
"type": "optional"
}
}
저도 비슷한 문제가 있었습니다.중첩된 클래스 속성 앞에 $를 추가했습니다.의심할 여지 없이 시도해 보다
@Query(value = "{ 'userId' : ?0, 'questions.$questionID' : ?1 }") List<PracticeQuestion> findPracticeQuestionByUserIdAndQuestionsQuestionID(int userId, int questionID);
언급URL : https://stackoverflow.com/questions/12730370/spring-data-mongodb-findby-method-for-nested-objects
'codememo' 카테고리의 다른 글
| 다른 Firebase 계정으로 앱 전송 (0) | 2023.06.27 |
|---|---|
| 암호에 따라 문자열을 인코딩하는 간단한 방법? (0) | 2023.06.27 |
| 기존 MVC 웹 응용 프로그램에 웹 API를 추가한 후 404 오류 발생 (0) | 2023.06.22 |
| 최대 연결 풀 크기 (0) | 2023.06.22 |
| Windows 경로를 Python 문자열 리터럴로 작성하는 방법은 무엇입니까? (0) | 2023.06.22 |