realm-js
realm-js copied to clipboard
Realm query objects by array of ids
Questions: I want to query by a list of ids but I get this error when I try to query by this:
byIds(ids: string[]) {
return this._realm
.objects(Provider)
.filtered('id IN $0',ids)
}
The expression following 'IN' must be a keypath to a list
Version of Realm and Tooling
- Realm JS SDK Version: 4.0.0-beta.0
- Node or React Native: 0.61.5
- Client OS & Version: Android
- Which debugger for React Native: None
Hey @pollend
Realm JS currently does not support IN
statement. We do this in our project by joining array with OR
like:
const idsQuery = [1,2,3,4].map(id => `userId = ${id}`).join(' OR ');
realm.objects().filtered(`(${idsQuery})`)
that's nice to know. I saw some sample code floating around that uses the IN
statement. will there be support for this in the future? seems like the query might become quite expensive if you have a large number of id's.
You need answer from Realm team. 😅
I based my answer on https://github.com/realm/realm-js/issues/450
We would like to implement full support for "IN" at some point, but because of the workaround mentioned here with chaining equality with "OR" it hasn't been a high priority. We do have an optimization at a lower level which combines these types of "equal OR equal" chains together, so even though you are writing out the query in long form, the execution should still be quite fast.
realm.objects().filtered(`(${idsQuery})`)
Can we do it on object ids?
@abhishekmatta999 yes, the workaround works on any type of value. If you are having issues with your query, let us know more details so we can try to help you.
@ironage Hi, Im getting this error when I'm trying it with object-ids
Invalid predicate: '(_id = 606b439ede7a330008506642 OR _id = 606b43a17375130009ef5864 OR _id = 606b43814e9a5900086fc20b OR _id = 606b438a3237c60008596144)': syntax error, unexpected identifier, expecting || or ')'
My query is:
let filteredQuery = publicationIds.map(id => _id = ${id}
).join(' OR ');
let result = await publicRealm.objects('catalogpublication').filtered((${filteredQuery})
)
@abhishekmatta999 the best practice is to pass your variables in by argument substitution, then you don't have to worry about the format. With the object id's stored in variables oid1
and oid2
the pattern looks like this:
realm.objects().filtered("_id = $0 OR _id = $1", oid1, oid2)
If you really need to hard code the object id's into the query string then they should be formatted into "oid(...)" like this:
realm.objects().filtered("_id = oid(606b439ede7a330008506642) OR _id = oid(606b43a17375130009ef5864)")
Hi,
Any update for 2022 usecases, IN operator is supported NOW!!
We need to filter object like this:
realm.objects('Car').filtered('id IN [1, 2, 3]');
Thanks!
Next release (v10.20.0) will include an enhancement of the IN
to support what os requested here.
Next release (v10.20.0) will include an enhancement of the
IN
to support what os requested here.
Hi @kneth,
First of All, thanks for this realease,
I have a question plz, what about 'NOT IN', how can i achieve this case ?
UPDATE
I use NOT id IN {1,2,3,4}
, and it's work!!!
@dridi93 You can use NONE
, ANY
and ALL
with IN
.
We haven't got around documenting it yet, but you can take a look at one of our tests: https://github.com/realm/realm-js/blob/master/integration-tests/tests/src/tests/queries.ts#L76-L88
I am using v11.0.0-rc.1
and have seen errors when trying to use IN with a non-object list, I tried several query arguments and all resulted in the same error as #4596
class MyObject extends Realm.Object {
static schema = {
name: 'MyObject',
properties: {
Id: 'string',
}
}
}
// idList = ['id1', 'id2']
realm.objects(MyObject).filtered('Id IN $0', idList);
// idList = "['id1','id2']"
realm.objects(MyObject).filtered('Id IN $0', idList);
// idList = "{'id1', 'id2'}"
realm.objects(MyObject).filtered('Id IN $0', idList);
My current workaround is to just use filter()
and run the logic myself, which is good enough but obviously I'd like to use the DB level query if possible.
realm.objects(MyObject).filter(o => idList.includes(o.Id));
Hi @tehvgg, the earliest release in the 11 series to include "IN" query support is v11.0.0-rc.2
. We have been publishing release candidates for v11 in parallel with stable v10 development which produces the somewhat surprising effect that updating to a higher major version does not necessarily include a feature released in a lower major version. That said, we recently released v11.0.0 which I'd recommend updating to over the previous rc versions if you are able to adapt to the breaking changes.
@ironage I thought that might be the case, initially I couldn't upgrade past rc.1
as my environment is a bare expo (SDK 46) workflow tied to RN 0.69, but I'll try the new stable v11
if it's compatible with my environment.
Thanks!
EDIT: v11
is 0.70+ so I'll be waiting for Expo 47 :)
For me using realm 11.3.1 & realm/react 0.4.3 , I was not able to query the way I was thinking it would work... Its not accepting string array as parameter
participantsProfileIds - ['key1', 'key2']
realm.objects('User').filtered(`externalId IN $0`, participantsProfileIds)
Instead had to use the following workaround:
realm.objects('User').filtered(`externalId IN { ${participantsProfileIds.map(x => `'${x}'`).join(', ')} }`)
Not sure which is better, this one above or the ' OR '
solution... seems like both are nasty hacks
@geo-vi what is the error that you are getting when passing an array of strings as an argument for the $0
syntax? I would expect that to be working.
Not sure which is better, this one above or the ' OR ' solution...
It is more efficient to use the x IN {...}
syntax over the chained OR solution.
@ironage
@geo-vi what is the error that you are getting when passing an array of strings as an argument for the
$0
syntax? I would expect that to be working.
no error however, I am not getting results either.
the arg that I am passing is a simple string array - ['key1', 'key2']
@geo-vi could you open a new bug report in this repository? It would be very helpful to include the exact string array argument and query in a minimal reproduction case if you are able to make one that doesn't include user data.
Finally i found a way for it to query by multiple object ids in react native.
const idsQuery = selectedItemIds.map(id => `oid(${id})`).join(', ');
const selectedItems = items.filtered(`_id IN { ${idsQuery} }`);