Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Realm query objects by array of ids #2781

Closed
pollend opened this issue Mar 31, 2020 · 20 comments
Closed

Realm query objects by array of ids #2781

pollend opened this issue Mar 31, 2020 · 20 comments

Comments

@pollend
Copy link

pollend commented Mar 31, 2020

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

image

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
@pollend pollend closed this as completed Mar 31, 2020
@pollend pollend reopened this Mar 31, 2020
@bimusiek
Copy link
Contributor

bimusiek commented Apr 1, 2020

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})`)

@pollend
Copy link
Author

pollend commented Apr 1, 2020

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.

@bimusiek
Copy link
Contributor

bimusiek commented Apr 1, 2020

You need answer from Realm team. 😅

I based my answer on
#450

@ironage
Copy link
Contributor

ironage commented Apr 1, 2020

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.

@abhishekmatta999
Copy link

realm.objects().filtered(`(${idsQuery})`)

Can we do it on object ids?

@ironage
Copy link
Contributor

ironage commented Apr 23, 2021

@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.

@abhishekmatta999
Copy link

abhishekmatta999 commented Apr 23, 2021

@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}))

@ironage
Copy link
Contributor

ironage commented Apr 23, 2021

@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)")

@dridi93
Copy link

dridi93 commented May 20, 2022

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!

@kneth
Copy link
Member

kneth commented Aug 23, 2022

Next release (v10.20.0) will include an enhancement of the IN to support what os requested here.

@kneth kneth closed this as completed Aug 23, 2022
@dridi93
Copy link

dridi93 commented Aug 25, 2022

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!!!

@kneth
Copy link
Member

kneth commented Aug 25, 2022

@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

@tehvgg
Copy link

tehvgg commented Oct 21, 2022

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));

@ironage
Copy link
Contributor

ironage commented Oct 21, 2022

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.

@tehvgg
Copy link

tehvgg commented Oct 21, 2022

@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 :)

@geo-vi
Copy link

geo-vi commented Mar 27, 2023

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

@ironage
Copy link
Contributor

ironage commented Mar 27, 2023

@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.

@geo-vi
Copy link

geo-vi commented Mar 27, 2023

@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']

@ironage
Copy link
Contributor

ironage commented Mar 27, 2023

@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.

@hardik-javascript
Copy link

hardik-javascript commented May 16, 2023

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} }`);

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Mar 15, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

10 participants