我需要在 Google Cloud Datastore 中使用什么索引才能根据 ID 和其他属性进行过滤?

sce*_*eee 1 node.js google-cloud-datastore google-cloud-node

我使用 Google Cloud Datastore 来存储由数据存储生成的 ID 作为主键的实体。此外,在本例中,我还存储每个实体的其他属性owner

实体在 Google Cloud Datastore 控制台中如下所示:

|Name/ID             |owner           |...|
|id=5657437197565952 |5634472569470976|...|
Run Code Online (Sandbox Code Playgroud)

然后我想根据key (id)和 属性过滤实体owner过滤实体。

为此,我知道我需要一个复合索引才能同时过滤字段(id)和所有者。所以我使用以下index.yaml文件创建了一个复合索引:

indexes:
- kind: job
  ancestor: no
  properties:
  - name: __key__
  - name: owner

# AUTOGENERATED
Run Code Online (Sandbox Code Playgroud)

索引显示在云控制台中,如果我使用云控制台 UI 过滤这两个字段,它会过滤表中的正确实体。我在那里做的过滤器是:

  • 键的大小等于:key(job,5657437197565952)
  • 所有者等于字符串:5634472569470976

但是,当我尝试使用以下代码通过 Google 的 Node.js 库检索该实体时,我没有得到任何结果:

const {Datastore} = require('@google-cloud/datastore');

async function quickStart() {
  const projectId = 'myproject';

  // Creates a client
  const datastore = new Datastore({
    projectId: projectId,
  });

  const keySelector = datastore.key(['myentity', '5657437197565952']);
  const query = datastore.createQuery('myentity').filter('key', keySelector).filter('owner', '=', '5634472569470976');

  const val = await query.run((err, entities, info) => {
    console.log(entities);
  });

  console.log('Got ' + val);
}
quickStart().catch(console.error);
Run Code Online (Sandbox Code Playgroud)

它们entities是空的,val如果字符串化则如下:

[[],{"moreResults":"NO_MORE_RESULTS","endCursor":"CgA="}]
Run Code Online (Sandbox Code Playgroud)

我还尝试使用名称id而不是创建另一个索引__key__,但没有成功。

我现在的问题是:我需要什么复合索引来对两个字段执行此过滤器,以便 NodeJS 代码也正确检索实体?

Dan*_*scu 5

由于您拥有密钥 ID,因此无需再担心查询、过滤器和索引:最多可以有一个实体与此类查询匹配,您可以通过直接密钥查找来获取该实体。我认为应该是这样的(抱歉,我不太懂 Node.js):

const key = datastore.key(['myentity', 5657437197565952]);
const entity = await datastore.get(key);
Run Code Online (Sandbox Code Playgroud)

一个积极的副作用是关键查找具有强一致性(查询最终一致),请参阅Cloud Datastore 中的最终一致性中的比较表。

但是,如果您坚持对键进行过滤,那么您必须使用特殊__key__名称来引用该属性(就像您在索引文件中所做的那样)。来自过滤器

主要过滤器

要过滤实体键的值,请使用特殊属性 __key__

在你的情况下,它会是这样的:

const keySelector = datastore.key(['myentity', 5657437197565952]);
const query = datastore.createQuery('myentity')
                       .filter('__key__', '=', keySelector)
                       .filter('owner', '=', '5634472569470976');
Run Code Online (Sandbox Code Playgroud)

id请注意,对象创建中的键keySelector需要不带引号!