按顺序在不同字段上按顺序存储一个范围查询 [英] Firestore one range query with order by on different field

查看:45
本文介绍了按顺序在不同字段上按顺序存储一个范围查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下收藏/文档

Location Collection
{
  "geoHash" : "wwscjrm3nu01",
  "timeStamp" : "March 25, 2020 at 1:07:38 PM UTC-4" 
}
{
  "geoHash" : "wwscjrm2wc2h",
  "timeStamp" : "March 25, 2020 at 2:07:38 PM UTC-4" 
}

请用上面的示例替换GeoHashs#

please replace the GeoHashs# with the example above

因此,我尝试通过按时间戳"DESC"对它们进行排序来查询这些GeoHash的范围,如以下

So, I was trying to query a range of those GeoHashs with ordering them by timestamp "DESC", Like the following

    db.collection('location')
        .where('geoHash', '>=', 'wwkxt4kxmmvk')
        .where('geoHash', '<=', 'wwt4vsn22peq')
        .orderBy('timeStamp', 'DESC')
        .limit(15).get()

它不起作用,请显示以下错误

It didn't work, please the error below

Error getting documents { Error: 3 INVALID_ARGUMENT: inequality filter property and first sort order must be the same: geoHash and timeStamp
at callErrorFromStatus (/srv/node_modules/@grpc/grpc-js/build/src/call.js:30:26)
at Http2CallStream.call.on (/srv/node_modules/@grpc/grpc-js/build/src/call.js:79:34)
at emitOne (events.js:121:20)
at Http2CallStream.emit (events.js:211:7)
at process.nextTick (/srv/node_modules/@grpc/grpc-js/build/src/call-stream.js:97:22)
at _combinedTickCallback (internal/process/next_tick.js:132:7)
at process._tickDomainCallback (internal/process/next_tick.js:219:9)
code: 3,
details: 'inequality filter property and first sort order must be the 
same: geoHash and timeStamp',
metadata: Metadata { internalRepr: Map {}, options: {} } }

如果我每个月或每天有成千上万个文档,该怎么办!?你们中的任何人都面临这个问题吗?解决该问题的最佳方法是什么?

What if I have thousands or millions of documents in this collection per month or day!? Does anyone of you face this problem and what's the best way to work around it?

更新0.2

非常感谢您在解决此问题方面的帮助和支持.我转载了我最后看到的东西.

I really appreciate your help and support in solving this issue. I have reproduced what I see in my end.

当前,我正在对Node js使用以下查询

Currently, I am using the following query with Node js

       db.collection('locations')
        .where('geoHash', '>=', 'wwkxt4kxmmvk')
        .where('geoHash', '<=', 'wwt4vsn22peq')
        .orderBy('geoHash')
        .orderBy('timeStamp', 'desc')
        .limit(15).get().then(snapshot => {
          if (snapshot.empty) {
            console.log('No matching documents.');
          }
          snapshot.forEach(doc => {
            console.log(doc.data());
          });
        });

期望正在过滤GeoHashs>订购GeoHashs>按时间戳对其进行订购.因此,最终结果应该是有序的时间戳,但我看到的是以下内容,

The expectation is filtering the GeoHashs > Order the GeoHashs > Order it by timestamp. So, the end results suppose to ordered timestamp, but I see is the following,

10:08:24.901 AM
   test
    { geoHash: 'wwscjrm3nu01',
      timeStamp: Timestamp { _seconds: 1585227600, _nanoseconds: 0 },
      post: '3' }
10:08:24.900 AM
   test
    { geoHash: 'wwscjrm3nu01',
      timeStamp: Timestamp { _seconds: 1585317000, _nanoseconds: 0 },
      post: '1' }
10:08:24.900 AM
   test
    { geoHash: 'wwscjrm2wc2h',
      timeStamp: Timestamp { _seconds: 1585314000, _nanoseconds: 0 },
      post: '2' }

如您在上面的输出中看到的,我只是基于timeStamp看到Post 1> 2> 3,但是我在上面看到的是Post 2> 1> 3.

As you see in the output above, I am excepting to see Post 1 > 2 > 3 based on timeStamp, but what i see above is Post 2 > 1 > 3.

推荐答案

所以您的有效查询是:

db.collection('locations')
  .orderBy("geoHash")
  .where('geoHash', '>=', range.lower)
  .where('geoHash', '<=', range.upper)
  .orderBy('timeStamp', 'DESC')
  .limit(15).get()

根据我所看到的结果,您将按 geoHash 进行排序,然后才按 timeStamp 进行排序.因此:如果两个文档具有相同的 geoHash 值,则它们将按照其 timeStamp 值的顺序排列.

From what I see the results you get are ordered by geoHash, and only then by timeStamp. So: if two documents have the same geoHash value, they will be in order of their timeStamp value.

这按预期工作:在字段上进行范围查询时,始终始终需要在该字段上进行排序.而且,由于您是第一次在该字段上订购,因此结果会以该字段的顺序返回.

This is working as intended: when you do a range query on a field, you always first need to order on that field. And since you first order on that field, the results come back in the order of that field.

这是Firestore的查询模型所固有的,因此可能有助于了解更多信息.它的性能保证意味着,一旦找到查询的起点,它就必须始终能够从数据库中流式传输结果.对未知数量的结果重新排序将使无法始终满足性能保证的要求,因此不支持此操作.

This is inherent about Firestore's query model, so it may help to know more about that.. It's performance guarantees mean that it must always be able to stream the results from the database once it's found the starting point for your query. Re-ordering an unknown number of results would make it impossible to always satisfy that performance guarantee, so is not a supported operation.

要按时间戳的顺序获取结果,您需要在应用程序代码中对其重新排序.

To get the results in order of their timestamps, you'll want to reorder them in your application code.

这篇关于按顺序在不同字段上按顺序存储一个范围查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆