#node.js #azure-cosmosdb
Вопрос:
Согласно документации, вы должны иметь возможность прочитать поток изменений из базы данных Azure CosmosDB в Node.js. К сожалению, я не нашел никакого кода для этого. Вот моя попытка, но я не могу заставить ее работать. Я дважды входил в ветвь hasMoreResults, но без каких-либо результатов в ответе. Код на C#, который я написал, работает без проблем.
import { CosmosClient } from './node_modules/@azure/cosmos/dist/index.js';
import https from 'https';
const db = 'MyNewDb';
const containerName = 'MyNewContainer';
const endpoint = 'https://localhost:8081';
const key = 'myKey';
const partitionKey = { kind: 'Hash', paths: ['/hello'] };
const client = new CosmosClient({
endpoint,
agent: new https.Agent({
rejectUnauthorized: false,
}),
key,
});
const dbResponse = await client.databases.createIfNotExists({
id: db,
});
const database = dbResponse.database;
const containerResponse = await database.containers.createIfNotExists(
{
id: containerName,
partitionKey,
},
{ offerThroughput: 400 },
);
const container = containerResponse.container;
const feedIterator = container.items.changeFeed('/hello', { startFromBeginning: true });
let count = 0;
while (feedIterator.hasMoreResults) {
console.log('more results', count ); // I get here twice but no items in feeIteratorResponse.result
const feedIteratorResponse = await feedIterator.fetchNext();
console.log(feedIteratorResponse);
}
Вот мой код на C#, который работает и дает мне все результаты.
class Program
{
static async Task Main(string[] args)
{
var dbId = "MyNewDb";
var containerId = "MyNewContainer";
using var client = new CosmosClient("https://localhost:8081", "myKey");
var container = client.GetContainer(dbId, containerId);
var changeFeedIterator = container.GetChangeFeedIterator<dynamic>(ChangeFeedStartFrom.Beginning(), ChangeFeedMode.Incremental);
while (changeFeedIterator.HasMoreResults)
{
var response = await changeFeedIterator.ReadNextAsync();
foreach (var item in response)
{
Console.WriteLine(item);
}
}
}
}
Ответ №1:
Ваша проблема в этой строке:
const feedIterator = container.items.changeFeed('/hello', { startFromBeginning: true });
API для ленты изменений позволяет считывать ленту изменений для определенного значения ключа раздела или для всего контейнера.
Код, который вы используете в C#, считывает поток изменений для всего контейнера, поэтому яблоки к яблокам будут:
const feedIterator = container.items.changeFeed({ startFromBeginning: true });
Если вы хотите прочитать ленту изменений для определенного ключа раздела, вам нужно использовать значение, а не определение ключа раздела.
const feedIterator = container.items.changeFeed('someValue', { startFromBeginning: true });
Где someValue
представляет значение ключа раздела некоторых документов, хранящихся в контейнере.
Комментарии:
1. Последний образец со значением работает. Тх! Но я хотел бы получить канал изменения для всего контейнера, как в вашем примере с яблоками на яблоки. К сожалению, я получаю ошибку:
"Container is partitioned, but no partition key or partition key range id was specified."
у вас тоже есть ответ на этот вопрос?2. Я бы поднял вопрос о репо SDK , с точки зрения API, похоже, что это должно сработать. docs.microsoft.com/en-us/javascript/api/@azure/cosmos/…
3. Я открыл проблему с репо, надеюсь, они смогут это прояснить. github.com/Azure/azure-sdk-for-js/issues/18062