【问题标题】:Firestore order by time but sort by IDFirestore 按时间排序,但按 ID 排序
【发布时间】:2018-10-05 06:02:20
【问题描述】:

我一直在尝试找出一种方法来查询文档列表,其中我在一个字段上有一个范围过滤器并按另一个字段排序,这当然是不可能的,请参阅我的另一个问题:Order by timestamp with range filter on different field Swift Firestore

但是是否可以将带有时间戳的文档保存为 id,然后默认排序?或者也许硬编码一个 ID,然后检索最后创建的文档 ID 并将 id 增加一个以供下一个要上传的帖子?

这显示了文档在集合中的排序方式

任何想法如何存储文档,以便在集合中创建它们?

【问题讨论】:

标签: swift firebase google-cloud-firestore


【解决方案1】:

Firebase 控制台中显示的文档顺序与使用 Firestore 的代码的功能几乎无关。控制台仅用于浏览数据,如果您知道其 ID,那么该排序方案可以相对直观地找到您可能正在寻找的文档。您无法在控制台中更改此排序顺序。

您的代码显然会有其他要求,这些要求应该编码到您的查询中,而不考虑您在仪表板中看到的任何排序顺序。如果您希望对文档进行基于时间的排序,则必须在文档中存储某种时间戳字段,并将其用于排序。我不建议使用时间戳作为文档的 ID,因为这可能会在将来给您带来问题。

【讨论】:

  • 您是否点击了上面的链接?它解释说,在一个字段上创建范围过滤器并按另一个字段排序时,无法创建查询。
  • 当我使用 getDocuments 将数据提取到我的应用程序中时,它们的排序方式与在 firestore 的控制台中相同。这只是巧合吗?
  • 如果您需要文档的排序顺序,您应该在查询中指定一个。如果您不这样做,文档不会定义排序顺序,因此您不应依赖偶然行为。
  • 你刚刚打破了一个简单解决方案的梦想哈哈,但这确实回答了我的问题,谢谢。
  • @DougStevenson 这不是偶然行为:“默认情况下,查询会按文档 ID 升序检索满足查询的所有文档。”
【解决方案2】:

它将order by document ID (ascending) by default in Swift

你可以使用 .order(by: '__id__')the better/documented way is with FieldPath documentID() 我不太了解 Swift 但我认为它类似于...

.order(by: FirebaseFirestore.FieldPath.documentID())

JavaScript 也有一个内部变量,它只返回 __id__

.orderBy(firebase.firestore.FieldPath.documentId())

有趣的是,__name__ 也可以工作,但它会对整个路径进行排序,包括集合名称(当然还有 id)。

【讨论】:

  • .order(by: 'name') 这有语法错误,请在发布之前检查您的答案,因为这会浪费我们的时间;)
  • 已更新以使其执行order(by: '__id__'),但没有下划线是故意的,否则它将引用名为“id”或“name”的字段而不是文档 id(或完整路径,在__name__)的情况
  • 我认为这也是一样的:.orderBy(firebase.firestore.FieldPath.documentId())
  • @bmm 不错的发现!!这是一个更好更惯用的解决方案,它甚至被记录在案啊哈
【解决方案3】:

是的,你可以这样做。

默认情况下,查询检索所有满足查询的文档 按文档 ID 升序排列。

在此处查看文档:https://firebase.google.com/docs/firestore/query-data/order-limit-data

因此,如果您找到一种方法来使用时间戳或其他主键值,其中升序的字典顺序是您想要的,您可以按任何字段进行过滤,并且仍然按主键升序对结果进行排序。

如果使用数字键(例如自纪元以来的秒数或整数序列),请注意将数字补零至最大精度。 10 按字典顺序小于 2,但 10 大于 02。

使用 ISO 格式的 YYYY-mm-ddTHH:MM:SS 日期时间字符串会起作用,因为它们自然地按升序排序。

【讨论】:

  • 当您可以简单地将适当的时间戳值存储为字段并按该字段排序时,为什么要这样做?在这种情况下,依赖这种默认行为似乎没有意义。
  • OP 发布了一个问题,即无法过滤一个字段并在另一个字段上排序。但我想知道这现在还没有过时吗? IIRC 我已经使用复合索引完成了这项工作,至少是通过 Web API。
【解决方案4】:

如果我正确理解您的需求,通过执行以下操作,您应该得到正确的顺序:

为每个文档添加一个类型为 number 的特定字段,例如 sortNbr 并指定一个您计算的时间戳作为值(例如,纪元时间,请参阅 Get Unix Epoch Time in Swift

然后构建一个按此字段值排序的查询,例如:

let docRef = db.collection("xxxx")
docRef.order(by: "sortNbr")

在此处查看文档:https://firebase.google.com/docs/firestore/query-data/order-limit-data

【讨论】:

    猜你喜欢
    • 2020-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多