简体   繁体   English

基于 Firestore 中的文档字段限制数据

[英]Limiting data based on document field in Firestore

I am playing around with Firebase Firestore for my data needs.我正在使用 Firebase Firestore 来满足我的数据需求。 I have a data model where there is a collection of apples, each document representing a unique apple which has a field of type object which is essentially a map of <string, string>我有一个数据模型,其中有一个苹果集合,每个文档代表一个唯一的苹果,它有一个对象类型的字段,它本质上是 <string, string> 的映射

Think of each apple document like:把每个苹果文档想象成这样:

name: "SiberianApple",
weight: "400g"
color: {
  today: "green",
  yesterday: "red", 
  tomorrow: "crimson"
}

Reading through the docs, I understood that we can query collections in various ways, but is it possible to limit the amount of information a client needs to fetch while fetching a document.通过阅读文档,我了解到我们可以通过各种方式查询集合,但是是否可以限制客户端在获取文档时需要获取的信息量。 Can I have a query on this field color such that it only returns我可以对这个字段color进行查询,以便它只返回

name: "SiberianApple",
weight: "400g",
color: {
   today: "green"
}

Basically something like graphql, where I can ask for what I want.基本上类似于graphql,在那里我可以要求我想要的东西。 Wanted to know if it's possible to query or should this field be a subcollection of this document so that I can query colors using path apples/<appleId>/colors for the subCollection?想知道是否可以查询或者该字段是否应该是本文档的子集合,以便我可以使用路径apples/<appleId>/colors查询子集合的apples/<appleId>/colors

Cloud Firestore listeners fire on the document level. Cloud Firestore 侦听器在文档级别触发。 There is no way to get triggered with just particular fields in a document or split the document to get only one property.无法仅通过文档中的特定字段触发或拆分文档以仅获取一个属性。 It's the entire document or nothing.它是整个文档或什么都没有。 So the Firestore client-side SDKs always return complete documents.因此 Firestore 客户端 SDK 始终返回完整的文档。 Unfortunately, there is no way to request only a part of the document.不幸的是,无法仅请求文档的一部分。

is it possible to limit the amount of information.是否可以限制信息量。

As said, that's not possible.如前所述,这是不可能的。 What you can do, is to create another collection with documents that can only hold the fields you need.您可以做的是使用只能包含您需要的字段的文档创建另一个集合。 This practice is called denormalization , and it's a quite common practice when it comes to NoSQL databases.这种做法称为反规范化,在 NoSQL 数据库中这是一种非常普遍的做法。

As Alex explained in his answer, with the Client SDKs it is not possible to get only a subset of the fields of a Document.正如 Alex 在他的回答中所解释的那样,使用客户端 SDK 不可能只获取文档字段的子集。 When you fetch a Document you get it with all its fields.当你获取一个 Document 时,你会得到它的所有字段。

However, this is possible with the Firestore REST API : With the REST API you can use a DocumentMask when you fetch one document with the get method.但是,这可以通过Firestore REST API 实现:通过 REST API,您可以在使用get方法获取一个文档时使用DocumentMask The DocumentMask will "restrict a get operation on a document to a subset of its fields". DocumentMask将“将DocumentMask的 get 操作限制为其字段的子集”。


For querying several documents, it is a bit different: you use the runQuery method.对于查询多个文档,它有点不同:您使用runQuery方法。 The request body shall contain a JSON object which has a structuredQuery property.请求正文应包含一个具有structuredQuery属性的 JSON 对象。

In turn, the StructuredQuery has a select property which contains a Projection object.反过来, StructuredQuery有一个select属性,其中包含一个Projection对象。

Here is an example of aa payload used when calling the runQuery method (ie https://firestore.googleapis.com/v1/{parent=projects/*/databases/*/documents}:runQuery ):以下是调用runQuery方法时使用的负载示例(即https://firestore.googleapis.com/v1/{parent=projects/*/databases/*/documents}:runQuery ):

const payloadObj = {
    structuredQuery: {
      where: {
        //  ....
      },
      orderBy: [
        {
          field: {
            fieldPath: 'name',
          },
          direction: 'ASCENDING',
        },
      ],
      from: [
        {
          collectionId: 'apples',
        },
      ],
      select: {
        fields: [
          {
            fieldPath: 'name',
          },
          {
            fieldPath: 'weight',
          },
          {
            fieldPath: 'color.today',
          },
        ],
      },
      limit: 1000,
    },
  };

As you can see in the code above, you can target only one of the properties of the color map, with fieldPath: 'color.today',正如您在上面的代码中看到的,您只能定位color映射的属性之一,使用fieldPath: 'color.today',


End note: The REST API is less user friendly than the client SDKs because you need to build the payload passed to the request and parse the responses but it is not difficult to use.尾注:REST API 的用户友好性不如客户端 SDK,因为您需要构建传递给请求的有效负载并解析响应,但它并不难使用。 In a web app, use fetch , axios or gaxios to execute the calls.在 Web 应用程序中,使用fetchaxiosgaxios来执行调用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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