Fix deleteDocuments

This commit is contained in:
Laurent Nguyen 2024-05-03 11:05:35 +02:00
parent 7c73a59ff5
commit e45ccf9aa4
2 changed files with 23 additions and 31 deletions

View File

@ -1,4 +1,4 @@
import { BulkOperationType, OperationInput, PartitionKey } from "@azure/cosmos"; import { BulkOperationType, OperationInput } from "@azure/cosmos";
import { CollectionBase } from "../../Contracts/ViewModels"; import { CollectionBase } from "../../Contracts/ViewModels";
import DocumentId from "../../Explorer/Tree/DocumentId"; import DocumentId from "../../Explorer/Tree/DocumentId";
import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils"; import { logConsoleInfo, logConsoleProgress } from "../../Utils/NotificationConsoleUtils";
@ -32,26 +32,26 @@ export const deleteDocument = async (collection: CollectionBase, documentId: Doc
* @param documentId * @param documentId
* @returns array of ids that were successfully deleted * @returns array of ids that were successfully deleted
*/ */
export const deleteDocuments = async ( export const deleteDocuments = async (collection: CollectionBase, documentIds: DocumentId[]): Promise<DocumentId[]> => {
collection: CollectionBase,
documentIds: {
id: string;
partitionKey?: PartitionKey;
}[],
): Promise<string[]> => {
const clearMessage = logConsoleProgress(`Deleting ${documentIds.length} ${getEntityName(true)}`); const clearMessage = logConsoleProgress(`Deleting ${documentIds.length} ${getEntityName(true)}`);
try { try {
const v2Container = await client().database(collection.databaseId).container(collection.id()); const v2Container = await client().database(collection.databaseId).container(collection.id());
const operations: OperationInput[] = documentIds.map((documentId) => ({ const operations: OperationInput[] = documentIds.map((documentId) => ({
...documentId, id: documentId.id(),
// bulk delete: if not partition key is specified, do not pass empty array, but undefined
partitionKey:
documentId.partitionKeyValue &&
Array.isArray(documentId.partitionKeyValue) &&
documentId.partitionKeyValue.length === 0
? undefined
: documentId.partitionKeyValue,
operationType: BulkOperationType.Delete, operationType: BulkOperationType.Delete,
})); }));
const bulkResult = await v2Container.items.bulk(operations); const bulkResult = await v2Container.items.bulk(operations);
const result: string[] = []; const result: DocumentId[] = [];
documentIds.forEach((documentId, index) => { documentIds.forEach((documentId, index) => {
if (bulkResult[index].statusCode === 204) { if (bulkResult[index].statusCode === 204) {
result.push(documentId.id); result.push(documentId);
} }
}); });
logConsoleInfo(`Successfully deleted ${getEntityName(true)}: ${result.length} out of ${documentIds.length}`); logConsoleInfo(`Successfully deleted ${getEntityName(true)}: ${result.length} out of ${documentIds.length}`);

View File

@ -802,24 +802,14 @@ const DocumentsTabComponent: React.FunctionComponent<{
* Implementation using bulk delete * Implementation using bulk delete
*/ */
let _deleteDocuments = useCallback( let _deleteDocuments = useCallback(
async (toDeleteDocumentIds: DocumentId[]): Promise<string[]> => { async (toDeleteDocumentIds: DocumentId[]): Promise<DocumentId[]> => {
onExecutionErrorChange(false); onExecutionErrorChange(false);
const startKey: number = TelemetryProcessor.traceStart(Action.DeleteDocuments, { const startKey: number = TelemetryProcessor.traceStart(Action.DeleteDocuments, {
dataExplorerArea: Constants.Areas.Tab, dataExplorerArea: Constants.Areas.Tab,
tabTitle, tabTitle,
}); });
setIsExecuting(true); setIsExecuting(true);
return deleteNoSqlDocuments( return deleteNoSqlDocuments(_collection, toDeleteDocumentIds)
_collection,
toDeleteDocumentIds.map((id) => ({
id: id.id(),
// bulk delete: if not partition key is specified, do not pass empty array, but undefined
partitionKey:
id.partitionKeyValue && Array.isArray(id.partitionKeyValue) && id.partitionKeyValue.length === 0
? undefined
: id.partitionKeyValue,
})),
)
.then( .then(
(deletedIds) => { (deletedIds) => {
TelemetryProcessor.traceSuccess( TelemetryProcessor.traceSuccess(
@ -858,9 +848,9 @@ const DocumentsTabComponent: React.FunctionComponent<{
onExecutionErrorChange(false); onExecutionErrorChange(false);
setIsExecuting(true); setIsExecuting(true);
_deleteDocuments(toDeleteDocumentIds) _deleteDocuments(toDeleteDocumentIds)
.then((deletedIds: string[]) => { .then((deletedIds: DocumentId[]) => {
// This could be optimized by using Set.has instead of array.includes const deletedRids = new Set(deletedIds.map((documentId) => documentId.rid));
const newDocumentIds = [...documentIds.filter((documentId) => !deletedIds.includes(documentId.id()))]; const newDocumentIds = [...documentIds.filter((documentId) => !deletedRids.has(documentId.rid))];
setDocumentIds(newDocumentIds); setDocumentIds(newDocumentIds);
setSelectedDocumentContent(undefined); setSelectedDocumentContent(undefined);
@ -1348,16 +1338,18 @@ const DocumentsTabComponent: React.FunctionComponent<{
* Mongo implementation * Mongo implementation
* TODO: update proxy to use mongo driver deleteMany * TODO: update proxy to use mongo driver deleteMany
*/ */
_deleteDocuments = (toDeleteDocumentIds: DocumentId[]): Promise<string[]> => { _deleteDocuments = (toDeleteDocumentIds: DocumentId[]): Promise<Document[]> => {
const promises = toDeleteDocumentIds.map((documentId) => _deleteDocument(documentId)); const promises = toDeleteDocumentIds.map((documentId) => _deleteDocument(documentId));
return Promise.all(promises); return Promise.all(promises);
}; };
const __deleteDocument = (documentId: DocumentId): Promise<void> => const __deleteDocument = async (documentId: DocumentId): Promise<void> => {
MongoProxyClient.deleteDocument(_collection.databaseId, _collection as ViewModels.Collection, documentId); await MongoProxyClient.deleteDocument(_collection.databaseId, _collection as ViewModels.Collection, documentId);
return documentId;
};
const _deleteDocument = useCallback( const _deleteDocument = useCallback(
(documentId: DocumentId): Promise<string> => { (documentId: DocumentId): Promise<DocumentId> => {
onExecutionErrorChange(false); onExecutionErrorChange(false);
const startKey: number = TelemetryProcessor.traceStart(Action.DeleteDocument, { const startKey: number = TelemetryProcessor.traceStart(Action.DeleteDocument, {
dataExplorerArea: Constants.Areas.Tab, dataExplorerArea: Constants.Areas.Tab,