在 Datastore 模式下使用 Cloud Firestore

Firestore 是一个 NoSQL 文档数据库,能够自动扩缩、具备出色的性能,并且易于进行应用开发。Firestore 是 Datastore 的最新版本;与 Datastore 相比,这个新版本引入了多项改进功能。

由于 Datastore 模式 Firestore 针对服务器用例和 App Engine 进行了优化,因此,对于主要将由 App Engine 应用使用的数据库,我们建议使用 Datastore 模式 Firestore。原生模式 Firestore 最适合移动和实时通知用例。如需详细了解 Firestore 模式,请参阅选择原生模式或 Datastore 模式

本文档介绍了如何使用 Google Cloud 客户端库将数据存储在 Datastore 模式数据库中,以及如何从 Datastore 模式数据库中检索数据。

前提条件和设置

请按照 App Engine Java 版“Hello, World!”中的说明设置您的环境和项目,并了解如何在 App Engine 中设计 Java 应用的结构。记录并保存项目 ID,因为您需要用它来运行本文档中介绍的示例应用。

克隆代码库

下载(克隆)示例:

git clone https://github.com/GoogleCloudPlatform/java-docs-samples
cd java-docs-samples/flexible/datastore

修改项目配置并设置依赖项

pom.xml 中,设置允许您使用 Datastore 模式的依赖项:

<!--  Using libraries-bom to manage versions.
See https://github.com/GoogleCloudPlatform/cloud-opensource-java/wiki/The-Google-Cloud-Platform-Libraries-BOM -->
<dependencyManagement>
  <dependencies>
    <dependency>
      <groupId>com.google.cloud</groupId>
      <artifactId>libraries-bom</artifactId>
      <version>25.0.0</version>
      <type>pom</type>
      <scope>import</scope>
    </dependency>
  </dependencies>
</dependencyManagement>

<dependencies>
  <dependency>
    <groupId>com.google.cloud</groupId>
    <artifactId>google-cloud-datastore</artifactId>
  </dependency>
</dependencies>

应用代码

示例应用会记录、检索和显示访问者的 IP。您会看到,日志条目是一个类型为 visit 的简单双字段类,系统会使用数据存储区 add() 命令将其保存为 Datastore 模式。然后,使用数据存储区 run() 命令以降序检索最近十条访问记录。

@SuppressWarnings("serial")
@WebServlet(name = "datastore", value = "")
public class DatastoreServlet extends HttpServlet {

  @Override
  public void doGet(HttpServletRequest req, HttpServletResponse resp)
      throws IOException, ServletException {
    // store only the first two octets of a users ip address
    String userIp = req.getRemoteAddr();
    InetAddress address = InetAddress.getByName(userIp);
    if (address instanceof Inet6Address) {
      // nest indexOf calls to find the second occurrence of a character in a string
      // an alternative is to use Apache Commons Lang: StringUtils.ordinalIndexOf()
      userIp = userIp.substring(0, userIp.indexOf(":", userIp.indexOf(":") + 1)) + ":*:*:*:*:*:*";
    } else if (address instanceof Inet4Address) {
      userIp = userIp.substring(0, userIp.indexOf(".", userIp.indexOf(".") + 1)) + ".*.*";
    }

    Datastore datastore = DatastoreOptions.getDefaultInstance().getService();
    KeyFactory keyFactory = datastore.newKeyFactory().setKind("visit");
    IncompleteKey key = keyFactory.setKind("visit").newKey();

    // Record a visit to the datastore, storing the IP and timestamp.
    FullEntity<IncompleteKey> curVisit =
        FullEntity.newBuilder(key).set("user_ip", userIp).set("timestamp", Timestamp.now()).build();
    datastore.add(curVisit);

    // Retrieve the last 10 visits from the datastore, ordered by timestamp.
    Query<Entity> query =
        Query.newEntityQueryBuilder()
            .setKind("visit")
            .setOrderBy(StructuredQuery.OrderBy.desc("timestamp"))
            .setLimit(10)
            .build();
    QueryResults<Entity> results = datastore.run(query);

    resp.setContentType("text/plain");
    PrintWriter out = resp.getWriter();
    out.print("Last 10 visits:\n");
    while (results.hasNext()) {
      Entity entity = results.next();
      out.format(
          "Time: %s Addr: %s\n", entity.getTimestamp("timestamp"), entity.getString("user_ip"));
    }
  }
}

使用 index.yaml 文件

示例应用会执行简单的查询。更为复杂的 Datastore 模式查询需要使用一个或多个索引,您必须在随应用一起上传的 index.yaml 文件中指定这些索引。此文件可以手动创建,也可以在本地测试应用时自动生成。

本地测试

如果您需要在本地开发和测试应用,则可以使用 Datastore 模式模拟器

了解详情

如需全面了解 Datastore 模式(包括优化和概念),请参阅 Datastore 模式 Firestore 文档