1

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

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

|Name/ID             |owner           |...|
|id=5657437197565952 |5634472569470976|...|

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

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

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

# AUTOGENERATED

该索引显示在云控制台中,如果我使用云控制台 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);

entities是空的,如果字符串化,则val如下所示:

[[],{"moreResults":"NO_MORE_RESULTS","endCursor":"CgA="}]

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

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

4

1 回答 1

4

由于您拥有密钥 ID,因此无需再为查询、过滤器和索引而烦恼:最多可以有一个实体与此类查询匹配,您可以通过直接密钥查找获得。我认为会是这样的(对不起,我不是 node.js 流利):

const key = datastore.key(['myentity', 5657437197565952]);
const entity = await datastore.get(key);

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

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

关键过滤器

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

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

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

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

于 2019-02-28T17:40:15.140 回答