如何为文件生成序列号?

时间:2019-02-20 19:22:42

标签: azure nosql azure-cosmosdb event-sourcing

我需要为插入集合中的每个文档分配一个序列号。 我发现以下建议,暗示该功能由“ 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");
        }
    }
}

0 个答案:

没有答案