【问题标题】:Querying data in firestore by timestamp按时间戳查询firestore中的数据
【发布时间】:2020-01-26 02:30:24
【问题描述】:

我正在按时间戳查询文档,它返回一个空数组。但是,当我使用 "==" ex:.where('date', '==',timestamp) 时它可以工作,并且在我使用 时返回空数组>'>=''。

我也尝试将时间戳转换为日期对象和字符串,但没有成功。

注意:firestore 中的date 字段的类型为Timestamp

我正在查询集合中日期大于“2018-08-03”的文档。

下面是交易集合(左)和文档(右)的图片,它应该是返回的文档数组的一部分,因为日期大于“2018-08-03”

下面是我的代码。

  const firstDay = new Date('2018-08-03');
  const timestamp1 = admin.firestore.Timestamp.fromDate(firstDay);
  const trans = [];
  const docRef = db.collection('Users').doc(uid).collection('transactions').where('item_id', '==', item_id)
    .where('date', '>=', timestamp1);
  await docRef.get()
    .then((snapshot) => {
      snapshot.forEach((doc) => {
        trans.push({ transaction_id: doc.id, transaction: doc.data() });
      });
    })
    .catch(err => new Error('cannot get the documents', err));

预期结果:应该是一个数组,其交易日期大于上面指定的日期。

实际结果:空数组。

由于它适用于平等 ==,我认为 >= 会起作用。我在这里遗漏了什么?

Logs after trying ">" (equal to timestamp1)

Firestore (2.3.0) 2019-10-03T14:01:25.013Z AObRG [ClientPool.acquire]: Re-using existing client with 100 remaining operations
Firestore (2.3.0) 2019-10-03T14:01:25.015Z AObRG [Firestore.readStream]: Sending request: {"parent":"projects/valuemo-000/databases/(default)/documents/Users/Xmr3vKT19OSST02DSTDMt0jSq692","structuredQuery":{"from":[{"collectionId":"transactions"}],"where":{"compositeFilter":{"op":"AND","filters":[{"fieldFilter":{"field":{"fieldPath":"item_id"},"op":"EQUAL","value":{"stringValue":"zGRkpP3QkzI89zKyDjZ7FPDrXd5G3Bco5ENlR"}}},{"fieldFilter":{"field":{"fieldPath":"date"},"op":"EQUAL","value":{"timestampValue":{"seconds":1533254400}}}}]}}}}
Firestore (2.3.0) 2019-10-03T14:01:25.232Z AObRG [Firestore._initializeStream]: Received stream error: { Error: The query requires a COLLECTION_ASC index 
for collection transactions and field date. That index is not ready yet. See its status here: https://console.firebase.google.com/project/valuemo-000/database/firestore/indexes/single_field?create_exemption=ClJwcm9qZWN0cy92YWx1ZW1vLTAwMC9kYXRhYmFzZXMvKGRlZmF1bHQpL2NvbGxlY3Rpb25Hcm91cHMvdHJhbnNhY3Rpb25zL2ZpZWxkcy9kYXRlEAEaCAoEZGF0ZRAB
    at Http2CallStream.call.on (D:\Projects\Valuemo-firebase\node_modules\@grpc\grpc-js\build\src\call.js:68:41)
    at Http2CallStream.emit (events.js:194:15)
    at process.nextTick (D:\Projects\Valuemo-firebase\node_modules\@grpc\grpc-js\build\src\call-stream.js:71:22)
    at process.internalTickCallback (internal/process/next_tick.js:70:11)
  code: 9,
  details:
   'The query requires a COLLECTION_ASC index for collection transactions and field date. That index is not ready yet. See its status here: https://console.firebase.google.com/project/valuemo-000/database/firestore/indexes/single_field?create_exemption=ClJwcm9qZWN0cy92YWx1ZW1vLTAwMC9kYXRhYmFzZXMvKGRlZmF1bHQpL2NvbGxlY3Rpb25Hcm91cHMvdHJhbnNhY3Rpb25zL2ZpZWxkcy9kYXRlEAEaCAoEZGF0ZRAB',
  metadata: Metadata { options: undefined, internalRepr: Map {} } }
Firestore (2.3.0) 2019-10-03T14:01:25.256Z AObRG [Firestore._initializeStream]: Received initial error: { Error: The query requires a COLLECTION_ASC index for collection transactions and field date. That index is not ready yet. See its status here: https://console.firebase.google.com/project/valuemo-000/database/firestore/indexes/single_field?create_exemption=ClJwcm9qZWN0cy92YWx1ZW1vLTAwMC9kYXRhYmFzZXMvKGRlZmF1bHQpL2NvbGxlY3Rpb25Hcm91cHMvdHJhbnNhY3Rpb25zL2ZpZWxkcy9kYXRlEAEaCAoEZGF0ZRAB
    at Http2CallStream.call.on (D:\Projects\Valuemo-firebase\node_modules\@grpc\grpc-js\build\src\call.js:68:41)
    at Http2CallStream.emit (events.js:194:15)
    at process.nextTick (D:\Projects\Valuemo-firebase\node_modules\@grpc\grpc-js\build\src\call-stream.js:71:22)
    at process.internalTickCallback (internal/process/next_tick.js:70:11)
  code: 9,
  details:
   'The query requires a COLLECTION_ASC index for collection transactions and field date. That index is not ready yet. See its status here: https://console.firebase.google.com/project/valuemo-000/database/firestore/indexes/single_field?create_exemption=ClJwcm9qZWN0cy92YWx1ZW1vLTAwMC9kYXRhYmFzZXMvKGRlZmF1bHQpL2NvbGxlY3Rpb25Hcm91cHMvdHJhbnNhY3Rpb25zL2ZpZWxkcy9kYXRlEAEaCAoEZGF0ZRAB',
  metadata: Metadata { options: undefined, internalRepr: Map {} } }
Firestore (2.3.0) 2019-10-03T14:01:25.260Z AObRG [Firestore._retry]: Request failed with unrecoverable error: { Error: The query requires a COLLECTION_ASC index for collection transactions and field date. That index is not ready yet. See its status here: https://console.firebase.google.com/project/valuemo-000/database/firestore/indexes/single_field?create_exemption=ClJwcm9qZWN0cy92YWx1ZW1vLTAwMC9kYXRhYmFzZXMvKGRlZmF1bHQpL2NvbGxlY3Rpb25Hcm91cHMvdHJhbnNhY3Rpb25zL2ZpZWxkcy9kYXRlEAEaCAoEZGF0ZRAB
    at Http2CallStream.call.on (D:\Projects\Valuemo-firebase\node_modules\@grpc\grpc-js\build\src\call.js:68:41)
    at Http2CallStream.emit (events.js:194:15)
    at process.nextTick (D:\Projects\Valuemo-firebase\node_modules\@grpc\grpc-js\build\src\call-stream.js:71:22)
    at process.internalTickCallback (internal/process/next_tick.js:70:11)
  code: 9,
  details:
   'The query requires a COLLECTION_ASC index for collection transactions and field date. That index is not ready yet. See its status here: https://console.firebase.google.com/project/valuemo-000/database/firestore/indexes/single_field?create_exemption=ClJwcm9qZWN0cy92YWx1ZW1vLTAwMC9kYXRhYmFzZXMvKGRlZmF1bHQpL2NvbGxlY3Rpb25Hcm91cHMvdHJhbnNhY3Rpb25zL2ZpZWxkcy9kYXRlEAEaCAoEZGF0ZRAB',
  metadata: Metadata { options: undefined, internalRepr: Map {} } }

【问题讨论】:

  • 请编辑问题以准确显示您希望由此查询返回的集合中的文档,以及firstDay 和所有其他变量的实际值。在没有看到实际数据的情况下,我们不知道您是否要查找与查询匹配的文档。你的问题应该说明查询肯定不符合你的期望,给大家看。
  • @DougStevenson 我添加了一张数据库结构的图片和一个包含其字段的文档。
  • 我认为您可能在比较错误的类型。您正在将日期与时间戳进行比较。时间戳值正在与日期类型进行比较。以下是更多信息:stackoverflow.com/questions/19141030/…
  • @Aye_baybae 日期与时间戳相当。这不是问题。仍然不清楚的问题是日期的时区。 2018-08-03 需要哪个时区?并非世界上的每个人都在同一天。
  • @DougStevenson 我忽略了时区,我不明白为什么使用 '==' 会返回具有特定时间戳但使用 '>=' 或 '

标签: javascript firebase google-cloud-firestore firebase-admin


【解决方案1】:

查询需要收集交易和字段日期的 COLLECTION_ASC 索引。该索引还没有准备好。

为什么不按照错误提示创建索引?这可能会从根本上解决您的问题。

【讨论】:

    【解决方案2】:

    所以我正在测试它,我认为与您提供的设置非常相似,我实际上能够重现相同的行为。

    在测试了不同的可能性后,我发现问题与字段的数据类型无关,而与复合索引的配置有关。

    使该查询工作所需的复合索引配置如下:

    根据文档的Queries supported by composite indexes 部分,此类复合查询的索引应首先具有相等过滤字段,这没有明确说明,但文档在示例中是这样表示的。

    如果这能帮您解决问题,请告诉我。

    【讨论】:

      【解决方案3】:

      获取您的日期并转换为 javascript 日期对象。然后在转换后的日期对象上执行 getTime() 它将返回一个数字。然后获取firestore时间戳并执行getSeconds()。将firestore时间戳的秒值与getTime()的变量存储输出进行比较。

      【讨论】:

      • 是的,但我应该如何在 where 子句中使用它?
      • 获取所有数据并将其存储在数组或对象等数据结构中。然后遍历它并比较它们中的每一个并将有效数据存储在另一个数组中然后使用它。没有办法直接使用 where 子句来比较两种不同类型的日期。此外,您不必在使用异步等待后使用 then 。直接在await之后写代码
      猜你喜欢
      • 2020-10-22
      • 2020-12-26
      • 2021-05-30
      • 2019-04-30
      • 2020-07-10
      • 1970-01-01
      • 1970-01-01
      • 2019-02-20
      • 1970-01-01
      相关资源
      最近更新 更多