10

I'm using realm to store my data on Android. Awesome framework! Now the only problem I'm now having is:

I got a array list strings with id's of Countries in my database.

Now I retrieve my Drinks that contains a relationship to countries.

Is there a way that I could to do a query like this:

String [] ids;

realm.where(Drinks.class).equalsTo("country.id", ids);

Something like that?

Or do I really need to do a query to get me all drinks and then filter the list manually?

EDIT:

My classes:

public class Drinks extends RealmObject {
    @PrimaryKey
    private String id;
    private String name;
    private Country country;
}

public class Country extends RealmObject {
    @PrimaryKey
    private String id;
    private String name;
}
user1007522
  • 7,858
  • 17
  • 69
  • 113
  • I would need to see your Drinks class and your Country class to tell you the answer. – EpicPandaForce Aug 18 '15 at 07:54
  • edited my question :-) – user1007522 Aug 18 '15 at 07:56
  • In that case, yes, the hypothetical query you mentioned would indeed work, it's described in the "LINK QUERIES" section of the docs. https://realm.io/docs/java/latest/#link-queries although I personally find that link queries are kinda slow, when I set the `country` in Realm I also set a field called `countryId` so that I don't need to use link queries - but that's just me. – EpicPandaForce Aug 18 '15 at 08:09
  • but neither contains or equalsTo takes an array as second parameter? – user1007522 Aug 18 '15 at 08:51
  • ...oh, that's what you meant. – EpicPandaForce Aug 18 '15 at 09:07
  • I asked the same question [here](http://stackoverflow.com/q/33651585/4034572). My solution does return an empty `RealmResults<>` if the list of ids is empty. – Albert Vila Calvo Nov 13 '15 at 14:43

4 Answers4

10

What you want to do is possible with link queries in theory (searching for "country.id"), however link queries are slow. Also you'd need to concatenate a bunch of or() predicates together, and I would not risk that with a link query.

I would recommend using the following

public class Drinks extends RealmObject {
    @PrimaryKey
    private String id;
    private String name;
    private Country country;
    @Index
    private String countryId;
}

public class Country extends RealmObject {
    @PrimaryKey
    private String id;
    private String name;
}

And when you set the Country in your class, you also set the countryId as country.getId().

Once you do that, you can construct such:

RealmQuery<Drinks> drinkQuery = realm.where(Drinks.class);
int i = 0;
for(String id : ids) {
    if(i != 0) {
        drinkQuery = drinkQuery.or();
    }
    drinkQuery = drinkQuery.equalTo("countryId", id);
    i++;
}
return drinkQuery.findAll();
EpicPandaForce
  • 79,669
  • 27
  • 256
  • 428
  • 1
    The lack of fundamental things like an IN operator, is extremely concerning and inconvenient. – RunLoop Jan 26 '16 at 07:40
  • 1
    @RunLoop honestly, you can make an IN operator with barely 5 lines. If you want to nitpick, talk about the lack of primitive RealmLists. – EpicPandaForce Jan 26 '16 at 07:47
  • 3
    Realm 1.2.0 added `in()` operator for `RealmQuery` – EpicPandaForce Aug 30 '16 at 12:22
  • @EpicPandaForce: can you help in this (https://stackoverflow.com/questions/49936344/print-realm-query-android?noredirect=1#comment86888280_49936344) – Mehta Apr 20 '18 at 07:44
8

Since the Realm database has added RealmQuery.in() with the version 1.2.0

I suggest using something like this.

//Drinks
public class Drinks extends RealmObject {
@PrimaryKey
private String id;
private String name;
private String countryId;

//getter and setter methods
}

//Country
public class Country extends RealmObject {
    @PrimaryKey
    private String id;
    private String name;

//getter and setter methods
}

The code to use inside activity/fragments to retrieve drink list

String[] countryIdArray = new String[] {"1","2","3"} //your string array
RealmQuery<Drinks> realmQuery  = realm.where(Drinks.class)
            .in("countryId",countryIdArray);
RealmResults<Drinks> drinkList = realmQuery.findAll();
Sagar Chapagain
  • 1,683
  • 2
  • 16
  • 26
1

In latest version of Realm 7+, you can use anyOf to match a field against a list of values.

anyOf("name", new String[]{"Jill", "William", "Trillian"})

in older versions, use in instead of anyOf and with kotlin use oneOf instead of in.

see this issue

All Іѕ Vаиітy
  • 24,861
  • 16
  • 87
  • 111
0

To match a field against a list of values, use in. For example, to find the names “Jill,” “William,” or “Trillian”, you can use in("name", new String[]{"Jill", "William", "Trillian"}). The in predicate is applicable to strings, binary data, and numeric fields (including dates).

Doc.-> https://realm.io/docs/java/latest#queries

All Іѕ Vаиітy
  • 24,861
  • 16
  • 87
  • 111
Raji Rajah
  • 63
  • 1
  • 1
  • 6