我需要为插入集合中的每个文档分配一个序列号。 我发现以下建议,暗示该功能由“ DocumentId(collection)”功能实现:
https://feedback.azure.com/forums/263030-azure-cosmos-db/suggestions/6408183-i-want-atomic-counter
当直接从.NET代码插入文档时:
var _cosmosClient = new CosmosClient(new CosmosConfiguration(endpoint, accountKey));
var _container = _cosmosClient.Databases[DatabaseId].Containers[ContainerId];
for (int i = 0; i < 15; i++) {
await _container.Items.CreateItemAsync("event", new { aggregateId = "event", id = Guid.NewGuid().ToString() });
}
当我如下查询集合时,函数“ DocmentId()”似乎返回一个递增的整数/序列,就像我需要的那样:
SELECT f.id, DocumentId(f) FROM Events f
[
{
"id": "2215dc32-89c1-464c-a559-0269be3068f4",
"$1": 9
},
{
"id": "ca6fac1c-59e1-42e2-858c-9646d6800a7e",
"$1": 10
},
{
"id": "54891f66-26de-461a-8ee7-2b23eb2d7c18",
"$1": 11
}
]
但是... 如果我改为通过存储过程插入多个文档,则DocumentId()函数的行为会有所不同。 现在,存储过程插入的所有文档都具有相同的值,并且该值只是一个大整数。
{
"id": "046f1a2b-7e6c-488b-af4c-bb06762dae9d",
"$1": 576460752303423500
},
{
"id": "d4f5a8d3-3e5a-456c-8ec9-3967a4250a08",
"$1": 576460752303423500
},
{
"id": "HEAD",
"$1": 576460752303423500
}
您知道从存储过程中插入文档时,为什么DocumentId函数的行为有所不同吗?
您知道如何为每个插入的文档分配一个自动递增的编号吗?
关于尼古拉斯
存储过程:
function appendEvents(header, docs, etag) {
var collection = getContext().getCollection();
var collectionLink = collection.getSelfLink();
// The count of imported docs, also used as current doc index.
var count = 0;
// Validate input.
if (!docs) throw new Error("The array is undefined or null.");
var docsLength = docs.length;
if (docsLength === 0) {
getContext().getResponse().setBody(0);
}
var options = { disableAutomaticIdGeneration: true };
// Call the CRUD API to create a document.
tryCreateEvent(docs[count], callback);
// Insert or update the header:
upsertStreamHeader(
header,
null,
function (err, doc, options) {
if (err) throw err;
}
);
function tryCreateEvent(doc, callback) {
// Assign the offset value relative from the header.offset:
//doc.offset = header.offset + count + 1;
var isAccepted = collection.createDocument(
collectionLink,
doc,
options,
callback
);
if (!isAccepted) getContext().getResponse().setBody(count);
}
// This is called when collection.createDocument is done and the document has been persisted.
function callback(err, doc, options) {
if (err) throw err;
// One more document has been inserted, increment the count.
count++;
if (count >= docsLength) {
// If we have created all documents, we are done. Just set the response.
getContext().getResponse().setBody(count);
} else {
// Create next document.
tryCreateEvent(docs[count], callback);
}
}
function upsertStreamHeader(doc, continuation, callback) {
var query = { query: "SELECT * FROM root r WHERE r.id = @id", parameters: [{ name: "@id", value: doc.id }] };
var requestOptions = { continuation: continuation };
var isAccepted = collection.queryDocuments(collectionLink, query, requestOptions, function (err, retrievedDocs, responseOptions) {
if (err)
{
throw err;
}
if (retrievedDocs.length > 0)
{
tryReplaceStreamHeader(retrievedDocs[0], doc, callback);
}
else
{
tryCreateStreamHeader(doc, callback);
}
});
if (!isAccepted) {
throw new Error("Unable to query documents");
}
}
function tryCreateStreamHeader(doc, callback) {
var isAccepted = collection.createDocument(collectionLink, doc, callback);
if (!isAccepted) {
throw new Error("Unable to schedule create document");
}
}
function tryReplaceStreamHeader(docToReplace, docContent, callback) {
var isAccepted = collection.replaceDocument(
docToReplace._self,
docContent,
{ etag: etag },
callback);
if (!isAccepted) {
throw new Error("Unable to schedule replace document");
}
}
}