简体   繁体   中英

Firebase - How to add orderBy to compound query?

Say I have some dummy data in my users collection:

[
  {email: 'foo@bar.com', claims: {admin: true}}
  {email: 'foo1@bar.com', claims: {admin: true}}
  {email: 'foo2@bar.com', claims: {support: true}}
  {email: 'foo3@bar.com', claims: {support: true}}
  {email: 'foo4@bar.com', claims: {support: true}}
]

Then I have these two queries:

const admins = this.db.collection('users', (ref) => ref
 .where('claims.admin', '==', true));
const support = this.db.collection('users', (ref) => ref
 .where('claims.support', '==', true));

Which I then combine to make a compound query:

this.dataSub = combineLatest(
  admins.valueChanges(),
  support.valueChanges()
)
.pipe(
  map((items) => {
    return [].concat(...items);
  })
)
.subscribe((items) => {
  this.items = items;
});

Now I would like to add things like orderBy to this query, but how would that work exactly? Putting an orderBy on them like:

const admins = this.db.collection('users', (ref) => ref
 .where('claims.admin', '==', true)
 .orderBy('email', 'asc'));
const support = this.db.collection('users', (ref) => ref
 .where('claims.support', '==', true)
 .orderBy('email', 'asc'));

And then combining the results won't make the final array of items sorted properly, since each list is sorted individually..

It feels like this should be documented somewhere but it's just not, how can I do this?

You're performing two separate queries on the same collection, and then merging them in your code (with combineLatest ). There are two things to keep in mind here:

  1. The separate queries may contain overlapping results. For example, a document with {email: 'foo@bar.com', claims: {admin: true, support: true}} would appear in both queries, and thus be in both results. Unless your use-case guarantees this will never happen, you'll need to decide what to do with such duplicate results.
  2. Since there are two separate result sets, there is no defined ordered for the combined results. Only you can determine what you want the final order to be, and you'll need to then make sure your merging code ensures that order. I'm not an RxJS expert, but would expect that you'd do this in the pipe operation.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM