Deleting files linked to record-
Map<Id, ERx_Import__ERx_Import_File_Details__c> importFiles = new Map<Id, ERx_Import__ERx_Import_File_Details__c>([Select Id from ERx_Import__ERx_Import_File_Details__c]);
// Step 1: Get the ContentDocument Id from the related record (e.g., Account)
List<ContentDocumentLink> links = [
SELECT ContentDocumentId
FROM ContentDocumentLink
WHERE LinkedEntityId in: importFiles.keySet()
];
// Step 2: Get the ContentDocument Ids
Set<Id> documentIds = new Set<Id>();
for (ContentDocumentLink link : links) {
documentIds.add(link.ContentDocumentId);
}
// Step 3: Delete ContentDocumentLink records
delete links;
// Step 4: Delete the ContentDocument records (this deletes file and its versions)
List<ContentDocument> docsToDelete = [SELECT Id FROM ContentDocument WHERE Id IN :documentIds];
delete docsToDelete;
Deleting files which are not linked to record-
you can delete files based on title match like below-
// Step 1: Fetch a batch of ContentDocuments
List<ContentDocument> docsToDelete = [SELECT Id FROM ContentDocument where Title like '%large_dataset_2%' LIMIT 50];
Set<Id> docIds = new Set<Id>();
for (ContentDocument doc : docsToDelete) {
docIds.add(doc.Id);
}
// Step 2: Check if any ContentDocumentLink exists
Map<Id, ContentDocumentLink> existingLinksMap = new Map<Id, ContentDocumentLink>(
[SELECT Id, ContentDocumentId FROM ContentDocumentLink WHERE ContentDocumentId IN :docIds]
);
// Step 3: Optional - check if linked to FeedItem (Chatter posts)
Map<Id, FeedAttachment> chatterLinks = new Map<Id, FeedAttachment>(
[SELECT Id, RecordId FROM FeedAttachment WHERE RecordId IN :docIds]
);
// Step 4: Only include docs that are not linked anywhere
List<ContentDocument> safeToDelete = new List<ContentDocument>();
for (ContentDocument doc : docsToDelete) {
if (!existingLinksMap.containsKey(doc.Id) && !chatterLinks.containsKey(doc.Id)) {
safeToDelete.add(doc);
}
}
// Step 5: Now delete the truly orphan files
if (!safeToDelete.isEmpty()) {
delete safeToDelete;
} else {
System.debug('No safe ContentDocuments found to delete.');
}