#google-cloud-firestore #google-cloud-datastore
#google-cloud-firestore #google-cloud-datastore
Вопрос:
Вот моя тестовая настройка, запущенная в эмуляторе хранилища данных с gcloud beta emulators datastore start --no-store-on-disk
При использовании клиента NodeJS настройка выполняется следующим образом. Обратите внимание, что для целей примера я использую простые комбинации Вид Имя для предка. Я знаю, что документ «Лучшая практика» не поощряет монотонно генерируемые пользовательские имена.
const namespace = 'test';
const datastore = new Datastore();
const entities: any[] = [];
const paths = [
['A', '1', 'Z', '1'],
['A', '2', 'Z', '1'],
['A', '3', 'Z', '1'],
['A', '4', 'Z', '1'],
];
for (const path of paths) {
const key = datastore.key({ path, namespace });
const data = {
text: 'Lorem Ipsum',
path: key.path.toString(),
};
entities.push({ key, data });
}
const transaction = datastore.transaction();
await transaction.run();
transaction.upsert(entities);
await transaction.commit();
// wait a second for things to persist.
await new Promise((resolve) => {
setTimeout(() => resolve(), 1000);
});
// Note that `hasAncestor` is **NOT** provided for this query.
const query = datastore.createQuery(namespace, 'Z');
const results = await datastore.runQuery(query);
expect(results[0]).toHaveLength(1); // fails, got 4 records back
Я бы ожидал, что при запросе для всех Z
объектов типа будет только 1 результат, если путь к предку не имел отношения к местоположению поиска объектов. Однако в моем тесте это не так, я получаю 4 результата обратно. Обратите внимание, что путь указан правильно для каждого объекта, возвращенного из запроса:
[
{
"path": "A,1,Z,1",
"text": "Lorem Ipsum"
},
{
"path": "A,2,Z,1",
"text": "Lorem Ipsum"
},
{
"path": "A,3,Z,1",
"text": "Lorem Ipsum"
},
{
"path": "A,4,Z,1",
"text": "Lorem Ipsum"
}
]
Итак, я хотел подтвердить, что это действительно правильное поведение, а не просто артефакт эмулятора. Если предполагается, что все работает именно так, из этого следует, что, возможно, можно подумать о создании временных рядов с использованием временных меток unix, если Вид Имя предка обеспечивает достаточную защиту от столкновения. В этом случае UUID, вероятно, будет достаточно, если процесс, запрашивающий запись, не выполняет запись в масштабе, который вызвал бы столкновение временных меток. В этом примере давайте предположим, что это 1 процесс на UUID, никогда больше.
['A', '95a69d2f-adac-4da7-b1ab-134ca0e7a840', 'Z', '1000000005000']
['A', '95a69d2f-adac-4da7-b1ab-134ca0e7a840', 'Z', '1000000006000']
['A', '95a69d2f-adac-4da7-b1ab-134ca0e7a840', 'Z', '1000000007000']
Или это все еще просто плохая идея?
Ответ №1:
Это правильное поведение, для объекта используется весь путь ключа, т. Е. он включает в себя все ключи-предки.
Если у вас есть уникальный (для каждого процесса) префикс, вам не нужно беспокоиться о монотонно увеличивающихся ключах, поскольку записи фактически распределяются в пространстве ключей вашим префиксом. Таким образом, это должно быть масштабируемое решение.