Azure Cosmos DB изменяет подачу с Node.js

#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