How to find Salesforce Enhanced Notes via SOQL

Salesforce Notes is a feature that let’s you add Notes on almost any Salesforce Record. In Salesforce Classic, they used to be simply Notes, but now in Salesforce Lightning, they upgraded to Enhanced Notes which can include rich text, lists and images and relate notes to more than one record.

This upgrade of course comes with a different structure. You can’t simply query notes by looking into the Notes sObject. While the Classic notes were stored in the Note sObject and its respective attachments were stored in the Attachment sObject; the new Lightning Enhanced Notes are stored in the Content object with a host of other sObjects (ContentDocumentContentVersionContentDocumentLink, and ContentNote) to go with and are accessed differently.

I came across this problem while trying to find some orphan Notes, which in the end were simply erroneously placed in Classic Notes instead of Lightning Enhanced Notes sObject. (See: How to Migrate Salesforce Classic Notes to Lightning Enhanced Notes).

Query Classic Salesforce Notes

You can query Classic Notes and it will bring the attachments as well.

List<Note> notes = [SELECT Id FROM Note WHERE ParentId = :mysampleRecord];
List<Attachment> attachments = [SELECT Id FROM Attachment WHERE ParentId = :mysampleRecord];

Pretty straightforward, right?

Salesforce Lightning Notes Structure

In Lightning, the sObject Content (which hosts Notes) has a different structure and it’s more complex. Notes and Attachments are represented by the ContentDocument sObject, which acts as a Parent object and hosts the versions of these attached files and Notes on possibly multiple linked ContentVersion records.

ContentDocument records stores the link to all the records Notes and Attachments are related to with entries on the  ContentDocumentLink sObject. (see: How to relink/unlink Notes to records)

The structure can get even more complicated with the existence of ContentNote, which acts as a facade object for ContentDocument but with only one ContentVersion in its Content field. You only use this ContentNote sObject when you’re adding new Notes.

Query Salesforce Lightning Notes

To query Notes and Attachments in Lightning for some object whose Id is mysampleRecord:

List<ContentDocumentLink> cdls = [SELECT ContentDocumentId FROM ContentDocumentLink WHERE LinkedEntityId = :myRecord];
Set<Id> documentIds = new Set<Id>();
for (ContentDocumentLink cdl : cdls) {
    documentIds.add(cdl.ContentDocumentId);
}
// ContentDocumentLink doesn't support semi-joins, which is frustrating.
List<ContentDocument> documents = [SELECT Id FROM ContentDocument WHERE Id IN :documentIds];

This query will bring ContentNote and regular ContentDocument Attachments.

If you’re only looking for Notes, you can query ContentNote sObject only. For ContentNote, request the Content field in your ContentNote query.

If you want just Attachments and not Notes, filter with FileType != 'SNOTE'.

To query the actual content of the Notes, for ContentDocument, query ContentVersion against ContentDocumentId and add IsLatest = true.

To query Notes with their Attachments, then use the following query:

SELECT ID
  ,Name
  ,(SELECT RecordType 
     FROM CombinedAttachments AS S 
     WHERE S.RecordType = 'Note' 
       OR S.RecordType = 'Attachment'
  ) 
FROM Account

You can replace Account with any other sObject that the notes are attached to and you’d like to query from.

How to Query Notes linked to Accounts

SELECT Id, ContentDocumentId, ContentDocument.Title,
	LinkedEntityId, LinkedEntity.Name
FROM ContentDocumentLink
WHERE LinkedEntityId IN (
	SELECT Id
	FROM Account
)
Was this article helpful?
YesNo