34

2 つのドメイン オブジェクトがあり、

@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 に基づいて「タイプ」を更新する必要があるため、カスタム リポジトリ インターフェイス内に findBy クエリ メソッドを記述しました。

public interface CustomRepository extends MongoRepository<PracticeQuestion, String> {

    List<PracticeQuestion> findByUserIdAndQuestionsQuestionID(int userId,int questionID);       
}

私の問題は、userId を 1、questionID を 3 としてこのメ​​ソッドを実行すると、questionID に関係なく質問リスト全体が返されることです。クエリ メソッド名は有効ですか、またはネストされたオブジェクトのクエリをどのように記述すればよいですか。

提案をありがとう。

4

4 に答える 4

40

@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.
}
于 2012-10-10T14:04:12.393 に答える
22

プロパティ式

前の例に示すように、プロパティ式は管理対象エンティティの直接プロパティのみを参照できます。クエリの作成時に、解析されたプロパティがマネージド ドメイン クラスのプロパティであることを確認します。ただし、ネストされたプロパティをトラバースすることで、制約を定義することもできます。個人が郵便番号付きの住所を持っていると仮定します。その場合、メソッド名List<Person> findByAddressZipCode(ZipCode zipCode); プロパティトラバーサル x.address.zipCode を作成します。解決アルゴリズムは、部分全体 (AddressZipCode) をプロパティとして解釈することから始まり、その名前 (大文字ではない) を持つプロパティのドメイン クラスをチェックします。アルゴリズムが成功すると、そのプロパティが使用されます。そうでない場合、アルゴリズムはキャメル ケース部分のソースを右側から頭と尾に分割し、対応するプロパティ (この例では AddressZip と Code) を見つけようとします。アルゴリズムがそのヘッドを持つプロパティを見つけた場合、テールを取得し、そこからツリーを構築し続け、説明した方法でテールを分割します。最初の分割が一致しない場合、アルゴリズムは分割ポイントを左 (住所、郵便番号) に移動して続行します。

これはほとんどの場合に機能するはずですが、アルゴリズムが間違ったプロパティを選択する可能性があります。Person クラスにも addressZip プロパティがあるとします。アルゴリズムは最初の分割ラウンドですでに一致し、本質的に間違ったプロパティを選択して最終的に失敗します (addressZip のタイプにはおそらくコード プロパティがないため)。このあいまいさを解決するには、メソッド名の中で _ を使用してトラバーサル ポイントを手動で定義します。したがって、メソッド名は次のようになります。

ユーザーデータリポジトリ:

List<UserData> findByAddress_ZipCode(ZipCode zipCode);

UserData findByUserId(String userId);

プロファイルリポジトリ:

Profile findByProfileId(String profileId);

UserDataRepositoryImpl:

UserData userData =  userDateRepository.findByUserId(userId);

Profile profile = profileRepository.findByProfileId(userData.getProfileId());

userData.setProfile(profile);

サンプル ポジョ :

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

リポジトリ クラスの上記の Document/POJO の場合:

UserData findByProfile_Email(文字列メール);

ref の場合: http://docs.spring.io/spring-data/data-commons/docs/1.6.1.RELEASE/reference/html/repositories.html

于 2015-01-19T08:51:34.363 に答える