How would I query a structure like this:
public class Animal extends RealmObject {
RealmList<Bird> birds;
}
public class Bird extends RealmObject {
int type;
RealmList<RealmInteger> species;
}
RealmInteger is an object with an int value
I want to find all Animal
objects that have Bird
which has a species of value
3 AND that Bird
is of type
2
I tried this but it keeps ignoring the type
:
realm.where(Animal.class)
.equalTo("birds.type", 2)
.equalTo("birds.species.value", 3)
.findAll();
My guess is it finds a match with value but doesn't check the type field at the same time. I need a way of doing .equalTo("birds.species.value", 3)
to check only Birds of type
2?
Update: Tried the @EpicPandaForce answer below, it is also returning this Animal with the data:
"birds": [
{
"species": [3, 15, 26],
"type": 1
},
{
"species": [],
"type": 2,
}
]
Because this Animal
does not have a species value
of 3 (it's empty) of type
2, it should NOT return it. Yet it does.
realm.where(Animal.class)
.equalTo("birds.type", 2)
.findAll()
.where()
.equalTo("birds.species.value", 3)
.findAll();
This trick is only needed for multiple link queries.
Unfortunately, you are running into a peculiarity of how link queries work, and currently, there is no easy way to do what you want.
The underlying reason is that you are querying from the point of view of Animal
and that you have two levels of RealmList
. What you are after is a sort of sub-query that isn't yet supported by Realm. The details of how link queries work are described here: https://realm.io/docs/java/latest/#link-queries. I would highly recommend working through the example in those docs.
That said, it is still possible to achieve what you want, but you need a combination of our newly added @LinkingObjects
annotation + some manually work to do it. Here is how:
// Animal class must have a stable hashcode. I did it by adding a primary key
// here, but it can be done in multiple ways.
public class Animal extends RealmObject {
@PrimaryKey
public String id = UUID.randomUUID().toString();
public RealmList<Bird> birds;
@Override
public boolean equals(Object o) {
// Make sure you have a stable equals/hashcode
// See https://realm.io/docs/java/latest/#realmobjects-hashcode
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Animal animal = (Animal) o;
return id.equals(animal.id);
}
@Override
public int hashCode() {
return id.hashCode();
}
}
// Add a @LinkingObjects field to Bird
// See https://realm.io/docs/java/latest/#inverse-relationships
public class Bird extends RealmObject {
public int type;
public RealmList<RealmInteger> species;
@LinkingObjects("birds")
public final RealmResults<Animal> animalGroup = null;
@Override
public String toString() {
return "Bird{" +
"type=" + type +
'}';
}
}
// Query the birds instead of Animal
RealmResults<Bird> birds = realm.where(Bird.class)
.equalTo("type", 2)
.equalTo("species.value", 3)
.findAll();
// You must collect all Animals manually
// See https://github.com/realm/realm-java/issues/2232
Set<Animal> animals = new HashSet<>();
for (Bird bird : birds) {
animals.addAll(bird.animalGroup);
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With