Query Realm for objects by IDs provided in a collection - android

I have a List<String> ids and I want all the FooRealmObjects that have the ID field included in the ids list.
I could iterate through the ids list and query objects by ID, but I was hoping there is a one-liner for this, like :
realm.where(Foo.class).in("id", ids).findAll();
Any ideas?

Now realm already support the feature you want.
Added in Realm Java 1.2.0. (https://github.com/realm/realm-java/issues/841)
Now you can do exactly what you want:
realm.where(Foo.class).in("id", ids).findAll();

As Jeremy mentioned, querying with a list of parameters is not possible (for now), but his answer does not work at all.
This is the workaround I used:
List<String> ids = ...;
Realm realm = Realm.getInstance(mContext);
RealmQuery<Foo> query = realm.where(Foo.class);
for (int i = 0; i < ids.size() - 1; i++) {
query = query.equalTo("id", ids.get(i)).or();
}
query = query.equalTo("id", ids.get(ids.size() - 1));
RealmResults<Foo> foos = query.findAll();

I don't believe there is a method according to the documentation to query like this. You could do something like the following:
RealmQuery query = realm.where(Foo.class);
for (String id : ids) {
query.equalTo("id", id).or();
}
query.findAll();
Might have to iterate through it using ;;; to remove the last .or() but I'm not sure.

Related

Firestore whereEqualsTo from arraylist

I'm trying to list documents that matches field String value from ArrayList.
Simply:
I have ArrayList with tags stored at runtime
and documents with field tag
and I want to query documents that matches tag with one of tags stored in ArrayList. Is this possible with official query or does I have to download all documents and filter it client-side? Thanks for any answers.
Also, this is my method generating query:
public static Query getQueryForFollowed(DocumentSnapshot snapshots) {
if (snapshots == null || !snapshots.exists()) {
return FirebaseFirestore.getInstance().collection("posts").whereEqualTo("null", "null"); // return query that will get nothing
}
ArrayList<String> f = processFollowedTags(snapshots);
Query query = FirebaseFirestore.getInstance()
.collection("posts")
.whereEqualTo("tag", f.get(0));
for (int i = 1; i < f.size(); i++) {
query = query.whereEqualTo("tag", f.get(i));
}
return query;
}
I have debugged code and query has contained requested conditions, but query didn't found any document matching it.
Try This
Query query = FirebaseFirestore.getInstance()
.collection("posts")
.whereEqualTo("tag", f.get(0)).orderBy("tag", Query.Direction.ASCENDING);;
After some more search on Google I have found that querying field to multiple values is not available.
According to:
https://stackoverflow.com/a/46633294/8428193
https://github.com/firebase/firebase-js-sdk/issues/321
Below code snippet may help you.
fun arrayContainsQueries() {
// [START array_contains_filter]
val citiesRef = db.collection("cities")
citiesRef.whereArrayContains("regions", "west_coast")
// [END array_contains_filter]
}
ref : git
As of Nov 2019 this is now possible to do with the in query.
With the in query, you can query a specific field for multiple values
(up to 10) in a single query. You do this by passing a list containing
all the values you want to search for, and Cloud Firestore will match
any document whose field equals one of those values.
it would look like this:
Query query = FirebaseFirestore.getInstance()
.collection("posts")
.whereIn("tag", f);

Realm Android merge two queries

I have a query, for my custom object which I form like this:
Path path = paths.get(i);
RealmList<RealmInt> ids = path.getPlaces();
query = realm.where(Place.class);
if(ids.size()==0){
} else {
int j = 0;
for (RealmInt id:ids){
if(j++>0){
query = query.or();
}
query = query.equalTo("id",id.getVal());
}
}
It's from some post at StackOverflow. Now, I want to add .contains to that query but it does not seem to work, it returns items like .contains is not there. Any idea ?
I found a solution, the key was to use beginGroup() and endGroup()

Fetch a single column from Realm Database (Android)

I'm a beginner in Realm.
I have a table with 3 columns which named Id, Name, Email,Address.
To get the data of Name column, we use a query like 'SELECT Name from table_name' for SQLite.
If we using Realm in Android, then which method do we have to use for fetching the data of only one column?
I searched alot on Google & documentation but to no avail.
Could anyone help me?
Update:
What I am tried:
RealmResults<User> results = query.findAll();
ArrayList<String> name = new Arraylist();
for(i=0; i<results.size; i++){
name.add(result.get(i).getName();
}
My problem:
results.size() > 10k. So I want to avoid 10k iteration
for(i=0; i<results.size; i++){
}
Look at queries section at the documentation:
All fetches (including queries) are lazy in Realm, and the data is never copied.
This mean, that data of particular column (property) will be fetched when you call getMyProperty() method. Not after call of finadAll() method of RealmQuery object
If we using Realm in Android, then which method do we have to use for fetching the data of only one column?
You can't, because Realm is an object store, it doesn't have concept of "columns".
My problem:
results.size() > 10k. So I want to avoid 10k iteration
for(i = 0; i < results.size(); i++){
}
Solution: don't iterate?
RealmResults<User> results = query.findAll();
//List<String> name = new ArrayList<>();
//for(i = 0; i < results.size(); i++){
// name.add(result.get(i).getName();
//}
return results;
// ...
String name = results.get(position).getName();

How to use between query function in realm database

I am using realm database for my android app. I wanna know how to use a query called "between" for a string. For example
final RealmResults<PersonModel> list = myRealm.
where(PersonModel.class).between("name","A","E").findAll();
its not working for the string which i have used.But its working only for int types. Can someone please help me.
final RealmResults<PersonModel> list = myRealm
.where(PersonModel.class)
.beginsWith("name","A")
.or().beginsWith("name","B")
.or().beginsWith("name","C")
.or().beginsWith("name","D")
.or().beginsWith("name","E")
.findAllSorted("name", Sort.ASCENDING);
According to https://realm.io/docs/java/latest/api/io/realm/RealmQuery.html query does not have method between accepting strings as parameters. Between usually can be replaced with pair of less-than and greater-than operators, but those does not support strings as well. So if you want to do between for strings lexicographically, the only way is to exclude between at all and do filtering in java.
Example:
final RealmResults<PersonModel> list = Realm.getDefaultInstance().where(PersonModel.class).findAll();
Collection<PersonModel> betweenModels = new ArrayList<>();
for (PersonModel m : list) {
if(m.getName().compareTo("A") >= 0 && m.getName().compareTo("E") <= 0) {
betweenModels.add(m);
}
}
betweenModels will contain items with names bigger-equal than "A" and less-equal than "E" lexicographically

Realm on Android - How to select multiple objects by list of ids (#PrimaryKey)?

I'm building an Android app with the Realm database.
I have a RealmObject subclass called Article which has an id field (it's and int and also a #PrimaryKey). I would like to pass to a query a list of ints (a Set, int[], or whatever) of article id's and retrieve only those articles.
In SQL would be like this:
SELECT *
FROM `table`
where ID in (5263, 5625, 5628, 5621)
I've seen it's possible to do this in iOS in this StackOverflow question.
How can I do this in Android? Thanks!
Edit: Just to inform, I also asked this on the GitHub repo here.
Update:
Realm 1.2.0 has added RealmQuery.in() for a comparison against multiple values. The documentation details all the available overloads. This one is the method we can use if our ids are Integers:
public RealmQuery<E> in(String fieldName, Integer[] values)
Original answer:
The answer from #ChristianMelchior returns all articles if the list of ids is empty. I want it to return an empty RealmResults<Article>. That's what I've ended up doing:
Set<Integer> articleIds = this.getArticleIds();
RealmQuery<Article> query = realm.where(Article.class);
if (articleIds.size() == 0) {
// We want to return an empty list if the list of ids is empty.
// Just use alwaysFalse
query = query.alwaysFalse();
} else {
int i = 0;
for (int id : articleIds) {
// The or() operator requires left hand and right hand elements.
// If articleIds had only one element then it would crash with
// "Missing right-hand side of OR"
if (i++ > 0) {
query = query.or();
}
query = query.equalTo("id", id);
}
}
return query.findAll();
Now realm v 1.2.0 support RealmQuery.in() for a comparison against multiple values.
The Realm Java API's doesn't support this yet unfortunately. You can follow the feature request here https://github.com/realm/realm-java/issues/841
The current work-around would be to build up the query yourself in a for-loop:
RealmResults<Article> articles = realm.allObjects(Article.class);
RealmQuery q = articles.where();
for (int id : ids) {
q = q.equalTo("id", id);
}
RealmResults<Article> filteredArticles = q.findAll();
This is the way Realm does it since 1.2.0:
public RealmQuery<E> in(String fieldName, String[] values) {
if (values == null || values.length == 0) {
throw new IllegalArgumentException(EMPTY_VALUES);
}
beginGroup().equalTo(fieldName, values[0]);
for (int i = 1; i < values.length; i++) {
or().equalTo(fieldName, values[i]);
}
return endGroup();
}
Previously this is how I did it
I just came across this post and I thought I could throw in my 2 cents on this. As much as I appreciate Christian Melchior and his answers I think in this case his answer is not working (at least in the current version).
I prefer to do it like this - I personally think it's more readable than Albert Vila's answer:
List<String> listOfIds = [..];
RealmQuery<SomeClass> query = realm.where(SomeClass.class);
boolean first = true;
for (String id : listOfIds) {
if (!first) {
query.or();
} else {
first = false;
}
query.equalTo("id", id);
}
RealmResults<SomeClass> results = query.findAll();

Categories

Resources