Какой индекс мне нужен в Google Cloud Datastore для фильтрации по ID и другому свойству?
Я использую Google Cloud Datastore для хранения объектов с сгенерированным идентификатором Datastore в качестве первичного ключа. Кроме того, я храню другие свойства для каждого объекта, в этом примере owner
,
Объект выглядит следующим образом в консоли хранилища данных Google Cloud:
|Name/ID |owner |...|
|id=5657437197565952 |5634472569470976|...|
Затем я хочу отфильтровать объекты на основе key (id)
и собственность owner
,
Для этого я понимаю, что мне нужен составной индекс, чтобы можно было фильтровать оба поля (id) и владельца одновременно. Поэтому я создал составной индекс, используя следующие index.yaml
файл:
indexes:
- kind: job
ancestor: no
properties:
- name: __key__
- name: owner
# AUTOGENERATED
Индекс отображается в облачной консоли, и если я фильтрую оба поля с помощью пользовательского интерфейса облачной консоли, он фильтрует правильную сущность в таблице. Фильтр, который я делаю, есть:
- Ключ точно такой же большой, как:
key(job,5657437197565952)
- владелец равен строке:
5634472569470976
Но когда я пытаюсь получить эту сущность с помощью библиотеки Node.js от Google, используя следующий код, я не получаю никакого результата:
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 также правильно извлекал сущность?
1 ответ
Поскольку у вас есть идентификатор ключа, вам больше не нужно беспокоиться о запросах, фильтрах и индексах: может быть максимум один объект, соответствующий такому запросу, который вы можете получить путем прямого поиска ключа. Я думаю, что было бы что-то вроде этого (извините, я не владею node.js):
const key = datastore.key(['myentity', 5657437197565952]);
const entity = await datastore.get(key);
Положительным побочным эффектом является то, что ключевые поиски строго согласованы (запросы в конечном итоге согласованы), см. Таблицу сравнения в разделе " Возможная согласованность в облачном хранилище данных".
Но если вы настаиваете на фильтрации по ключу, вам придется ссылаться на свойство с помощью специального __key__
имя (как вы сделали в вашем индексном файле). Из фильтров:
Ключевые фильтры
Чтобы отфильтровать значение ключа сущности, используйте специальное свойство
__key__
:
В вашем случае это будет примерно так:
const keySelector = datastore.key(['myentity', 5657437197565952]);
const query = datastore.createQuery('myentity')
.filter('__key__', '=', keySelector)
.filter('owner', '=', '5634472569470976');
Обратите внимание, что ключ id
в keySelector
создание объекта должно быть без кавычек!