Read Realm Objects - Kotlin SDK
On this page
Tip
Find Objects
Find Object by Primary Key
To find an object with a specific primary key value, open a realm
and query the primary key field for the desired primary key value
using realm.query().
Specify the object type as a type parameter passed to query()
:
// Search equality on the primary key field name val frogs: Frog? = realm.query<Frog>("_id == $0", PRIMARY_KEY_VALUE).first().find()
Find Objects of a Type
To find all objects of a type, open a realm and pass the type as a type parameter to realm.query():
// fetch all objects of a type as a flow, asynchronously val frogsFlow: Flow<ResultsChange<Frog>> = realm.query<Frog>().asFlow() val asyncCall: Deferred<Unit> = async { frogsFlow.collect { results -> when (results) { // print out initial results is InitialResults<Frog> -> { for (frog in results.list) { Log.v("Frog: $frog") } } else -> { // do nothing on changes } } } } // fetch all objects of a type as a results collection, synchronously val frogs: RealmResults<Frog> = realm.query<Frog>().find() for(frog in frogs) { Log.v("Frog: $frog") }
Query an Embedded Object
You can query an embedded object directly or through the parent object. You can also use the EmbeddedRealmObject.parent() method to access the parent of the embedded object.
// Query an embedded object directly val queryAddress: EmbeddedAddress = realm.query<EmbeddedAddress>("state == 'FL'").find().first() // Get the parent of an embedded object val getParent: Contact = queryAddress.parent() // Query through the parent object val queryContactAddresses: RealmResults<Contact> = realm.query<Contact>("address.state == 'NY'") .sort("name") .find()
Query a Dictionary Property
You can iterate and check the values of a RealmDictionary as you would a Kotlin Map.
// Find frogs who have forests with favorite ponds val frogs = realm.query<Frog>().find() val frogsWithFavoritePonds = frogs.query("favoritePondsByForest.@count > $0", 1).find() val thisFrog = frogsWithFavoritePonds.first() Log.v("${thisFrog.name} has favorite ponds in these forests: ") // You can iterate through keys or values for (key in thisFrog.favoritePondsByForest.keys) Log.v(key) // Check if a dictionary contains a key if (thisFrog.favoritePondsByForest.containsKey("Hundred Acre Wood")) { Log.v("${thisFrog.name}'s favorite pond in Hundred Acre Wood is ${thisFrog.favoritePondsByForest["Hundred Acre Wood"]}") } // Check if a dictionary contains a value if (thisFrog.favoritePondsByForest.containsValue("Picnic Pond")) { Log.v("${thisFrog.name}'s lists Picnic Pond as a favorite pond") }
Query a RealmSet Property
You can query a RealmSet property:
realm.write { // Create a Frog object named 'Kermit' // with a RealmSet of favorite snacks val frog = copyToRealm( Frog().apply { name = "Kermit" favoriteSnacks.add(Snack().apply { name = "Flies" }) favoriteSnacks.add(Snack().apply { name = "Crickets" }) favoriteSnacks.add(Snack().apply { name = "Worms" }) } ) // Query for frogs that have worms as a favorite snack val frogs = query<Frog>("favoriteSnacks.name == $0", "Worms").find().first() // Query for specific snacks val wormsSnack = frog.favoriteSnacks.first { it.name == "Worms" } }
Check if the RealmSet Contains Items
You can check if the RealmSet
contains one or more elements:
To check if the set contains a particular item, pass the element to set.contains().
To check if the
RealmSet
contains multiple items, pass the elements to set.containsAll().
Either method returns true
if the set contains the
specified elements.
val frog = query<Frog>("name == $0", "Kermit").find().first() val snackSet = findLatest(frog)?.favoriteSnacks // Check if the set contains a particular value val wormSnack = snackSet?.first { it.name == "Worms" } Log.v("Does Kermit eat worms?: ${snackSet?.contains(wormSnack)}") // true // Check if the set contains multiple values val containsAllSnacks = snackSet?.containsAll(snackSet) Log.v("Does Kermit eat flies, crickets, and worms?: $containsAllSnacks") // true
Filter Data
Filter Results
Filter results to retrieve a specific segment
of objects with realm.query().
In the argument of realm.query()
, use Realm Query Language to perform filtering.
Realm Query Language is a string-based query language that you can use to retrieve
objects from a realm.
Specify the object type as a type parameter passed to query()
.
For more information on constructing queries, refer to the Realm Query Language reference documentation.
// Find frogs where name is 'Michigan J. Frog' val michiganFrogs: RealmResults<Frog> = realm.query<Frog>("name = $0", "Michigan J. Frog").find() // Find frogs where age > 3 AND species is 'Green' val oldGreenFrogs: RealmResults<Frog> = realm.query<Frog>("age > $0 AND species = $1", 3, "green" ).find()
Filter with Full-Text Search
You can use Realm Query Language (RQL) to query on properties that
have Full-Text Search Indexes (FTS) on them. FTS supports Boolean matches and not relevance-based matches.
To query these properties, use the TEXT
predicate.
Words in the query are converted to tokens by a tokenizer using the following rules:
Tokens can only consist of characters from ASCII and the Latin-1 supplement (western languages). All other characters are considered whitespace.
Words split by a hyphen (
-
), for examplefull-text
, are split into two tokens.Tokens are diacritics- and case-insensitive.
You can search for an entire word or phrase or limit your results with the following characters:
Exclude results for a word by placing the
-
character in front of the word. For example,fiction -science
would include all search results forfiction
and exclude those that include the wordscience
.In Kotlin SDK version 1.11.0 and later, you can specify prefixes by placing the
*
character at the end of a word. For example,fict*
would include all search results forfiction
andfictitious
. (The Kotlin SDK does not currently support suffix searches.)
In the following example, we query the Book.genre
field:
// Find all books with "science fiction" as the genre val scienceFiction = realm.query<Book>("genre TEXT $0", "science fiction").find() // Find all books with "fiction" but not "science" in the genre val fictionNotScience = realm.query<Book>("genre TEXT $0", "fiction -science").find() // Find all books with "sci-" and "fi-" prefixes in the genre val sciFi = realm.query<Book>("genre TEXT $0", "sci* fi*").find()
Sort Results
To sort results, specify a sort in the query passed to
realm.query()
with the SORT
keyword. Similarly, use DISTINCT
to constrain results to unique values of a field, and
LIMIT
to cap the number of results. The SDK
provides convenience methods on RealmQuery
so you don't have
to manually write the keywords:
When used on the same query in both RQL and method form, SORT
,
DISTINCT
, and LIMIT
execute in the order they're added
to the query. This can impact the results returned from your query.
// sort in descending order, frogs with distinct owners, only the first 5, with convenience methods val convenientlyOrganizedFrogs: Flow<ResultsChange<Frog>> = realm.query<Frog>("name = $0", "George Washington") .sort("age", Sort.DESCENDING).distinct("owner").limit(5).asFlow() val asyncCallConvenience: Deferred<Unit> = async { convenientlyOrganizedFrogs.collect { results -> when (results) { // print out initial results is InitialResults<Frog> -> { for (frog in results.list) { Log.v("Frog: $frog") } } else -> { // do nothing on changes } } } } // sort in descending order, frogs with distinct owners, only the first 5, using RQL val somewhatLessConvenientlyOrganizedFrogs: Flow<ResultsChange<Frog>> = realm.query<Frog>("name = $0 SORT(age DESC) DISTINCT(owner) LIMIT(5)", "George Washington").asFlow() val asyncCallLessConvenient: Deferred<Unit> = async { somewhatLessConvenientlyOrganizedFrogs.collect { results -> when (results) { // print out initial results is InitialResults<Frog> -> { for (frog in results.list) { Log.v("Frog: $frog") } } else -> { // do nothing on changes } } } }
Iterate Results
You can iterate through results using Flows
.
Tip
See also:
To learn more about Kotlin Flows, check out the kotlinx.coroutines documentation on Flows.
To convert your results into a Flow
, call realmQuery.asFlow().
Then iterate through the results with flow.collect():
// fetch frogs from the realm as Flowables val frogsFlow: Flow<ResultsChange<Frog>> = realm.query<Frog>().asFlow() // iterate through the flow with collect, printing each item val frogsObserver: Deferred<Unit> = async { frogsFlow.collect { results -> when (results) { // print out initial results is InitialResults<Frog> -> { for (frog in results.list) { Log.v("Frog: $frog") } } else -> { // do nothing on changes } } } } // ... some time later, cancel the flow so you can safely close the realm frogsObserver.cancel() realm.close()