Docs Menu
Docs Home
/ /
Atlas Device SDK
/ /

データのフィルタリング - Java SDK

項目一覧

  • クエリ エンジン
  • スムーズインターフェース
  • このセクションの例について
  • 比較演算子
  • 論理演算子
  • string演算子
  • 集計演算子
  • フィルタリング、ソート、制限、一意、チェーンのクエリ
  • このセクションの例について
  • フィルター
  • 結果を並べ替える
  • 結果を制限する
  • 一意の結果
  • チェーン クエリ
  • RQLを使用したクエリ

Realm 内のデータをフィルタリングするには、Realm クエリ エンジンを使用します。

Java SDK でクエリ エンジンにアクセスするには、次の 2 つの方法があります。

  • Flut インターフェース

  • RQL

Java SDK は Flut インターフェース を使用します クエリ エンジンに渡される複数句のクエリを構築します。

RealmQuery API を参照 利用可能なメソッドの完全なリストについては、 を参照してください。

Realm コレクションをフィルタリングするために使用できる演算子にはいくつかのタイプがあります。 フィルターは、フィルタリングされるコレクション内のすべてのオブジェクトの演算子式を評価することで機能します。 式が trueに解決される場合、Realm Database は結果コレクションにオブジェクトを含めます。

は、次のいずれかで構成されます。

  • 現在評価されているオブジェクトのプロパティの名前。

  • 演算子と最大 2 つの引数式(s)。

  • リテラルの string、数値、または日付。

このセクションの例では、タスク リスト アプリの単純なデータセットを使用します。 2 つの Realm オブジェクトタイプはProjectTaskです。 Taskには、名前、割り当て者の名前、完了したフラグがあります。 また、優先順位(値が大きいほど重要)と、その作業に費やされた時間数もあります。 Projectには 0 個以上のTasksがあります。

これらの 2 つのクラス、 ProjectTaskのスキーマを以下で参照してください。

ProjectTask.java
import org.bson.types.ObjectId;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import io.realm.annotations.RealmClass;
import io.realm.annotations.Required;
public class ProjectTask extends RealmObject {
@PrimaryKey
public ObjectId _id;
@Required
public String name;
public String assignee;
public int progressMinutes;
public boolean isComplete;
public int priority;
@Required
public String _partition;
}
Project.java
import org.bson.types.ObjectId;
import io.realm.RealmList;
import io.realm.RealmObject;
import io.realm.annotations.PrimaryKey;
import io.realm.annotations.RealmClass;
import io.realm.annotations.Required;
public class Project extends RealmObject {
@PrimaryKey
public ObjectId _id;
@Required
public String name;
public RealmList<ProjectTask> tasks = new RealmList<>();
}
ProjectTask.kt
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import io.realm.annotations.Required
import org.bson.types.ObjectId
open class ProjectTask(
@PrimaryKey
var _id: ObjectId = ObjectId(),
@Required
var name: String = "",
var assignee: String? = null,
var progressMinutes: Int = 0,
var isComplete: Boolean = false,
var priority: Int = 0,
var _partition: String = ""
): RealmObject()
Project.kt
import io.realm.RealmList
import io.realm.RealmObject
import io.realm.annotations.PrimaryKey
import io.realm.annotations.Required
import org.bson.types.ObjectId
open class Project(
@PrimaryKey
var _id: ObjectId = ObjectId(),
@Required
var name: String = "",
var tasks: RealmList<ProjectTask> = RealmList(),
): RealmObject()

検索の最も簡単な操作は、値を比較することです。

演算子
説明
between
左側の数値式または日付式が右側の範囲と等しい場合、 trueと評価されます。 日付の場合、左側の日付が右側の日付範囲内にある場合、これはtrueと評価されます。
equalTo
左側の式が右側の式と等しい場合は、 trueと評価されます。
greaterThan
左側の数値または日付式が右側の数値または日付式より大きい場合は、 trueと評価されます。 日付の場合、左側の日付が右側の日付より後の場合、これはtrueと評価されます。
greaterThanOrEqualTo
左側の数値または日付式が右側の数値または日付式より大きい場合、 trueと評価されます。 日付の場合、左側の日付が右側の日付より後のか同じである場合、これはtrueと評価されます。
in
左側の式が右側のリストにある場合は、 trueと評価されます。
lessThan
左側の数値または日付式が右側の数値または日付式より小さい場合は、 trueと評価されます。 日付の場合、左側の日付が右側の日付よりも前の場合、これはtrueと評価されます。
lessThanOrEqualTo
左側の数値式が右側の数値式より小さい場合、 trueと評価されます。 日付の場合、左側の日付が右側の日付よりも前の日付または同じ日付の場合、これはtrueと評価されます。
notEqualTo
左側の式が右側の式と等しくない場合、 trueと評価されます。

次の例では、クエリ エンジンの比較演算子を使用して次のようにします。

  • priorityプロパティ値の値をしきい値と比較して、優先順位の高いタスクを見つけます。どの優先順位を超えると、優先順位が高いと見なされます。

  • progressMinutesプロパティが特定の範囲内にあるかどうかを確認して、開始されたばかりのタスクまたは実行時間が短いタスクを見つけます。

  • assigneeプロパティがnullに等しいタスクを見つけて、割り当てられていないタスクを見つけます。

  • assigneeプロパティが名前のリストにあるかどうかを確認して、特定のチームメイト エイリアスまたはレイテンシに割り当てられたタスクを見つけます。

RealmQuery<ProjectTask> tasksQuery = realm.where(ProjectTask.class);
Log.i("EXAMPLE", "High priority tasks: " + tasksQuery.greaterThan("priority", 5).count());
Log.i("EXAMPLE", "Just-started or short tasks: " + tasksQuery.between("progressMinutes", 1, 10).count());
Log.i("EXAMPLE", "Unassigned tasks: " + tasksQuery.isNull("assignee").count());
Log.i("EXAMPLE", "Ali or Jamie's tasks: " + tasksQuery.in("assignee", new String[]{"Ali", "Jamie"}).count());
val tasksQuery = realm.where(ProjectTask::class.java)
Log.i("EXAMPLE", "High priority tasks: " + tasksQuery.greaterThan("priority", 5).count())
Log.i("EXAMPLE", "Just-started or short tasks: " + tasksQuery.between("progressMinutes", 1, 10).count())
Log.i("EXAMPLE", "Unassigned tasks: " + tasksQuery.isNull("assignee").count())
Log.i("EXAMPLE", "Ali or Jamie's tasks: " + tasksQuery.`in`("assignee", arrayOf("Ali", "Jamie")).count())

論理演算子を使用して複合述語を作成できます。

演算子
説明
and
左側の式と右側の式の両方がtrueである場合は、 trueと評価されます。
not
指定された式の結果を否定します。
or
いずれかの式がtrueを返す場合、 trueと評価されます。

クエリ言語の論理演算子を使用して、Ali の完了したタスクをすべて検索できます。 つまり、 assigneeプロパティ値が 'Ali' に等しく、かつisCompleteプロパティ値がtrueであるすべてのタスクを検索します。

RealmQuery<ProjectTask> tasksQuery = realm.where(ProjectTask.class);
Log.i("EXAMPLE", "Ali has completed " +
tasksQuery.equalTo("assignee", "Ali").and().equalTo("isComplete", true).findAll().size() +
" tasks.");
val tasksQuery = realm.where(ProjectTask::class.java)
Log.i("EXAMPLE", "Ali has completed " +
tasksQuery.equalTo("assignee", "Ali").and()
.equalTo("isComplete", true).findAll().size + " tasks.")

これらの string 演算子を使用して、string の値を比較できます。 正規表現のようなワイルドカードを使用すると、検索の柔軟性が向上します。

演算子
説明
beginsWith
左側の文字string式が右側のstring式で始まる場合は、true と評価されます。 これは contains と似ていますが、左側のstring式が右側のstring式の先頭にある場合にのみ一致します。
contains
左側のstring式が右側のstring式のどこにある場合は、true と評価されます。
endsWith
左側の文字string式が右側のstring式で終わる場合は、true と評価されます。 これは contains と似ていますが、左側のstring式が右側のstring式の最後に見つかった場合にのみ一致します。
like

左側の string 式が右側の string ワイルドカード string 式と一致する場合、 trueと評価されます。 ワイルドカードstring式は、2 つの特殊なワイルドカード文字を含む通常の文字を使用するstringです。

  • *ワイルドカードは、0 個以上の任意の文字と一致します

  • ?ワイルドカードは任意の文字に一致します。

たとえば、ワイルドカードstring 「d?g」は、「dog」、「dig」、および「dgs」と一致しますが、「ding」、「dg」、または「adog」には一致しません。

equalTo
左側の文字列が右側のstringと辞書的に等しい場合、trueと評価されstring 。

クエリ エンジンの string 演算子を使用して、名前が文字「e」で始まるプロジェクトと、名前に「ie」が含まれるプロジェクトを検索します。

RealmQuery<Project> projectsQuery = realm.where(Project.class);
// Pass Case.INSENSITIVE as the third argument for case insensitivity.
Log.i("EXAMPLE", "Projects that start with 'e': "
+ projectsQuery.beginsWith("name", "e", Case.INSENSITIVE).count());
Log.i("EXAMPLE", "Projects that contain 'ie': "
+ projectsQuery.contains("name", "ie").count());
val projectsQuery = realm.where(Project::class.java)
// Pass Case.INSENSITIVE as the third argument for case insensitivity.
Log.i("EXAMPLE", "Projects that start with 'e': "
+ projectsQuery.beginsWith("name", "e", Case.INSENSITIVE).count())
Log.i("EXAMPLE", "Projects that contain 'ie': "
+ projectsQuery.contains("name", "ie").count())

注意

大文字と小文字を区別しない文字の制限

大文字と小文字を区別しないstring演算子は、Latin BasicLatin SupplementLatin Extended ALatin Extended B (UTF-8 range 0–591) 文字セットのみをサポートします。 equalTonotEqualTocontainsendsWithbeginsWith 、またはlikeを使用する場合に、クエリで大文字と小文字を区別しないフラグを設定すると、英語のロケール文字でのみ機能します。

Realm オブジェクトのコレクション プロパティに集計演算子を適用できます。 集計演算子はコレクションを走査して、単一の値に縮小します。

演算子
説明
average
コレクション全体の特定の数値プロパティの平均値を評価します。
count
指定されたコレクション内のオブジェクトの数を評価します。
max
コレクション全体で特定の数値プロパティの最も高い値を評価します。
min
コレクション全体で特定の数値プロパティの最小値として評価されます。
sum
コレクション全体の指定された数値プロパティの合計を評価します。

データのさまざまなファセットを表示するために、フィルターがいくつか作成されます。

  • タスクの平均優先順位が 5 を超えるプロジェクト。

  • 長時間実行されているプロジェクト。

RealmQuery<ProjectTask> tasksQuery = realm.where(ProjectTask.class);
/*
Aggregate operators do not support dot-notation, so you
cannot directly operate on a property of all of the objects
in a collection property.
You can operate on a numeric property of the top-level
object, however:
*/
Log.i("EXAMPLE", "Tasks average priority: " + tasksQuery.average("priority"));
val tasksQuery = realm.where(ProjectTask::class.java)
/*
Aggregate operators do not support dot-notation, so you
cannot directly operate on a property of all of the objects
in a collection property.
You can operate on a numeric property of the top-level
object, however:
*/Log.i("EXAMPLE", "Tasks average priority: " + tasksQuery.average("priority"))

このセクションの例では、 TeacherStudentという 2 つの Realm オブジェクトタイプを使用します。

これら 2 つのクラスのスキーマは以下を参照してください。

Driver.java
import io.realm.RealmList;
import io.realm.RealmObject;
public class Teacher extends RealmObject {
private String name;
private Integer numYearsTeaching;
private String subject;
private RealmList<Student> students;
public Teacher() {}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Integer getNumYearsTeaching() { return numYearsTeaching; }
public void setNumYearsTeaching(Integer numYearsTeaching) { this.numYearsTeaching = numYearsTeaching; }
public String getSubject() { return subject; }
public void setSubject(String subject) { this.subject = subject; }
public RealmList<Student> getStudents() { return students; }
public void setStudents(RealmList<Student> students) { this.students = students; }
}
Atlas .java
import io.realm.RealmObject;
import io.realm.RealmResults;
import io.realm.annotations.LinkingObjects;
public class Student extends RealmObject {
private String name;
private Integer year;
@LinkingObjects("students")
private final RealmResults<Teacher> teacher = null;
public Student() {}
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Integer getYear() { return year; }
public void setYear(Integer year) { this.year = year; }
public RealmResults<Teacher> getTeacher() { return teacher; }
}
Driver.kt
import io.realm.RealmList
import io.realm.RealmObject
open class Teacher : RealmObject() {
var name: String? = null
var numYearsTeaching: Int? = null
var subject: String? = null
var students: RealmList<Student>? = null
}
ユーザー.kt
import io.realm.RealmObject
import io.realm.RealmResults
import io.realm.annotations.LinkingObjects
open class Student : RealmObject() {
var name: String? = null
var year: Int? = null
@LinkingObjects("students")
val teacher: RealmResults<Teacher>? = null
}

スムーズインターフェース の演算子メソッドを使用してフィルターを構築できます RealmQuery クラスによって公開される場合

// Build the query looking at all teachers:
RealmQuery<Teacher> query = realm.where(Teacher.class);
// Add query conditions:
query.equalTo("name", "Ms. Langtree");
query.or().equalTo("name", "Mrs. Jacobs");
// Execute the query:
RealmResults<Teacher> result1 = query.findAll();
// Or alternatively do the same all at once (the "Fluent interface"):
RealmResults<Teacher> result2 = realm.where(Teacher.class)
.equalTo("name", "Ms. Langtree")
.or()
.equalTo("name", "Mrs. Jacobs")
.findAll();
// Build the query looking at all teachers:
val query = realm.where(Teacher::class.java)
// Add query conditions:
query.equalTo("name", "Ms. Langtree")
query.or().equalTo("name", "Mrs. Jacobs")
// Execute the query:
val result1 = query.findAll()
// Or alternatively do the same all at once (the "Fluent interface"):
val result2 = realm.where(Teacher::class.java)
.equalTo("name", "Ms. Langtree")
.or()
.equalTo("name", "Mrs. Jacobs")
.findAll()

これにより、「Ms」という名前の指示を含む、クラスRealmResultsの新しいインスタンスが作成されます。 Longtree" または "数: James .

RealmQuery には、クエリを実行できるいくつかのメソッドが含まれています。

  • findAll()は、クエリ条件を満たすすべてのオブジェクトを検索するまでブロックします

  • findAllAsync()はすぐに戻り、クエリ条件を満たすすべてのオブジェクトをバックグラウンド スレッドで非同期に検索します

  • findFirst()は、クエリ条件を満たす最初のオブジェクトを見つけるまでブロックします

  • findFirstAsync()はすぐに戻り、バックグラウンド スレッドで非同期にクエリ条件を満たす最初のオブジェクトを検索します。

クエリは、 RealmResults型を使用して、一致する Realm オブジェクトへの参照のリストを返します。

オブジェクト プロパティを参照する場合、ドット表記を使用してそのオブジェクトの子プロパティを参照できます。 ドット表記 で埋め込みオブジェクト関係のプロパティを参照できます。

たとえば、"Wirt" または "Greg" という名前の学生が所属するすべてのドライバーに対するクエリを考えてみましょう。

// Find all teachers who have students with the names "Wirt" or "Greg"
RealmResults<Teacher> result = realm.where(Teacher.class)
.equalTo("students.name", "Wirt")
.or()
.equalTo("students.name", "Greg")
.findAll();
// Find all teachers who have students with the names "Wirt" or "Greg"
val result = realm.where(Teacher::class.java)
.equalTo("students.name", "Wirt")
.or()
.equalTo("students.name", "Greg")
.findAll()

ドット表記を使用して逆関係をクエリすることもできます。

// Find all students who have teachers with the names "Ms. Langtree" or "Mrs. Jacobs"
RealmResults<Student> result = realm.where(Student.class)
.equalTo("teacher.name", "Ms. Langtree")
.or()
.equalTo("teacher.name", "Mrs. Jacobs")
.findAll();
// Find all students who have teachers with the names "Ms. Langtree" or "Mrs. Jacobs"
val result = realm.where(Student::class.java)
.equalTo("teacher.name", "Ms. Langtree")
.or()
.equalTo("teacher.name", "Mrs. Jacobs")
.findAll()

重要

Realm は、 distinct()sort()limit()メソッドを指定した順序で適用します。 データセットによっては、クエリ結果が変更される可能性があります。 一般的に、意図しない結果セットを避けるためには、最後にlimit()を適用する必要があります。

sort()メソッドを使用してクエリ結果の順序を定義できます。

// Find all students in year 7, and sort them by name
RealmResults<Student> result = realm.where(Student.class)
.equalTo("year", 7)
.sort("name")
.findAll();
// Alternatively, find all students in year 7
RealmResults<Student> unsortedResult = realm.where(Student.class)
.equalTo("year", 7)
.findAll();
// then sort the results set by name
RealmResults<Student> sortedResult = unsortedResult.sort("name");
// Find all students in year 7, and sort them by name
val result: RealmResults<Student> = realm.where(Student::class.java)
.equalTo("year", 7L)
.sort("name")
.findAll()
// Alternatively, find all students in year 7
val unsortedResult: RealmResults<Student> = realm.where(Student::class.java)
.equalTo("year", 7L)
.findAll()
// then sort the results set by name
val sortedResult = unsortedResult.sort("name")

ソートは、デフォルトで結果を昇順で整理します。 結果を降順で並べ替えるには、2 番目の引数としてSort.DESCENDINGを渡します。 単一のプロパティではなくプロパティの配列を渡すことで、同一のプロパティ値間のソート順序の同値を解決できます。同点の場合、Realm は関連付けられているオブジェクトを後続のプロパティで順番にソートします。

注意

stringソートの制限

Realm は大文字と小文字に対して非標準のソートを使用し、大文字が最初にソートされるのではなく、まとめてソートされます。 その結果、 '- !"#0&()*,./:;?_+<=>123aAbBcC...xXyYzZが Realm の実際のソート順になります。 また、文字列のソートでは、 Latin BasicLatin SupplementLatin Extended ALatin Extended B (UTF-8 range 0–591)文字セットのみがサポートされます。

limit()メソッドを使用して、クエリ結果の数を特定の最大数に制限できます。

// Find all students in year 8, and limit the results collection to 10 items
RealmResults<Student> result = realm.where(Student.class)
.equalTo("year", 8)
.limit(10)
.findAll();
// Find all students in year 8, and limit the results collection to 10 items
val result: RealmResults<Student> = realm.where(Student::class.java)
.equalTo("year", 8L)
.limit(10)
.findAll()

限定的な結果コレクションは、他のクエリ結果と同様に自動的に更新されます。 その結果、基礎となるデータの変更として、オブジェクトがコレクションから削除される可能性があります。

Tip

Realm の最適化ではページ分割は必要ありません

一部のデータベースでは、ディスクから不要なデータを読み取ったり、メモリを使用しすぎたりするのを避けるために、結果を制限してページ分割することを推奨しています。

Realm クエリは遅延されるため、このような測定を行う必要はありません。 Realm は、明示的にアクセスされた場合にのみ、クエリ結果からオブジェクトをロードします。

Tip

限定的な結果での削除通知

コレクション通知では、結果セットから削除されたオブジェクトが削除されたと報告されます。 これは必ずしも基礎の Realm から削除されたことを意味するわけではなく、クエリ結果の一部ではなくなったことを意味します。

distinct()メソッドを使用して、特定のフィールドのクエリ結果を一意の値に縮小できます。

// Find all students in year 9, and cap the result collection at 10 items
RealmResults<Student> result = realm.where(Student.class)
.equalTo("year", 9)
.distinct("name")
.findAll();
// Find all students in year 9, and cap the result collection at 10 items
val result: RealmResults<Student> = realm.where<Student>(Student::class.java)
.equalTo("year", 9L)
.distinct("name")
.findAll()

distinct()は、整数、long、短い、およびStringフィールドでのみ呼び出せます。他のフィールド型では例外がスローされます。 ソートと同様に、同点を解決するために複数のフィールドを指定できます。

where()メソッドを呼び出すと、結果コレクションに追加のフィルターを適用できます。

// Find all students in year 9 and resolve the query into a results collection
RealmResults<Student> result = realm.where(Student.class)
.equalTo("year", 9)
.findAll();
// filter the students results again by teacher name
RealmResults<Student> filteredResults = result.where().equalTo("teacher.name", "Ms. Langtree").findAll();
// Find all students in year 9 and resolve the query into a results collection
val result: RealmResults<Student> = realm.where(Student::class.java)
.equalTo("year", 9L)
.findAll()
// filter the students results again by teacher name
val filteredResults =
result.where().equalTo("teacher.name", "Ms. Langtree").findAll()

where()メソッドから返されるRealmQueryは、 findメソッドを使用してRealmResultsに解決できます。 フィルタリングされた結果では、元の結果セットと同じタイプのオブジェクトのみが返されますが、それ以外の場合は任意のフィルターを使用できます。

バージョン 10.4.0 の新機能

また、Realm からオブジェクトを取得するときに検索を制限する string ベースのクエリ言語であるRQLを使用してRealmをクエリすることもできます。

RealmQuery.rawPredate()を使用できます。 構文、使用、および制限の詳細については、 RQLリファレンスを参照してください。

RQLでは、 Realmモデル クラスで定義されたクラス名とプロパティ名、または @RealmField で定義された内部名のいずれかを使用できます。 未加工の述語を、 RealmQueryで作成された他の未加工の述語またはタイプセーフな述語と組み合わせることができます。

// Build a RealmQuery based on the Student type
RealmQuery<Student> query = realm.where(Student.class);
// Simple query
RealmResults<Student> studentsNamedJane =
query.rawPredicate("name = 'Jane'").findAll();
// Multiple predicates
RealmResults<Student> studentsNamedJaneOrJohn =
query.rawPredicate("name = 'Jane' OR name = 'John'").findAll();
// Collection queries
RealmResults<Student> studentsWithTeachers =
query.rawPredicate("teacher.@count > 0").findAll();
RealmResults<Student> studentsWithSeniorTeachers =
query.rawPredicate("ALL teacher.numYearsTeaching > 5").findAll();
// Sub queries
RealmResults<Student> studentsWithMathTeachersNamedSteven =
query.rawPredicate("SUBQUERY(teacher, $teacher, $teacher.subject = 'Mathematics' AND $teacher.name = 'Mr. Stevens').@count > 0").findAll();
// Sort, Distinct, Limit
RealmResults<Student> students =
query.rawPredicate("teacher.@count > 0 SORT(year ASCENDING) DISTINCT(name) LIMIT(5)").findAll();
// Combine two raw predicates
RealmResults<Student> studentsNamedJaneOrHenry =
query.rawPredicate("name = 'Jane'")
.rawPredicate("name = 'Henry'").findAll();
// Combine raw predicate with type-safe predicate
RealmResults<Student> studentsNamedJaneOrHenryAgain =
query.rawPredicate("name = 'Jane'")
.equalTo("name", "Henry").findAll();
// Build a RealmQuery based on the Student type
val query = realm.where(Student::class.java)
// Simple query
val studentsNamedJane = query.rawPredicate("name = 'Jane'").findAll()
// Multiple predicates
val studentsNamedJaneOrJohn =
query.rawPredicate("name = 'Jane' OR name = 'John'").findAll()
// Collection queries
val studentsWithTeachers =
query.rawPredicate("teacher.@count > 0").findAll()
val studentsWithSeniorTeachers =
query.rawPredicate("ALL teacher.numYearsTeaching > 5").findAll()
// Sub queries
val studentsWithMathTeachersNamedSteven =
query.rawPredicate("SUBQUERY(teacher, \$teacher, \$teacher.subject = 'Mathematics' AND \$teacher.name = 'Mr. Stevens').@count > 0")
.findAll()
// Sort, Distinct, Limit
val students =
query.rawPredicate("teacher.@count > 0 SORT(year ASCENDING) DISTINCT(name) LIMIT(5)")
.findAll()
// Combine two raw predicates
val studentsNamedJaneOrHenry = query.rawPredicate("name = 'Jane'")
.rawPredicate("name = 'Henry'").findAll()
// Combine raw predicate with type-safe predicate
val studentsNamedJaneOrHenryAgain =
query.rawPredicate("name = 'Jane'")
.equalTo("name", "Henry").findAll()

Tip

詳細: RQL例

次のページにも役立つRQLの例があります。

戻る

削除