@@ -118,10 +118,7 @@ class NoteContentFulltextExp extends Expression {
118118 // Single word: look for =word with word boundaries
119119 // Split by = to get attribute values, then check each value for exact word match
120120 const parts = normalizedFlatText . split ( '=' ) ;
121- matches = parts . slice ( 1 ) . some ( part => {
122- const words = part . split ( / \s + / ) ;
123- return words . some ( word => word === normalizedPhrase ) ;
124- } ) ;
121+ matches = parts . slice ( 1 ) . some ( part => this . exactWordMatch ( normalizedPhrase , part ) ) ;
125122 } else {
126123 // Multi-word phrase: check for substring match
127124 matches = normalizedFlatText . includes ( `=${ normalizedPhrase } ` ) ;
@@ -136,6 +133,17 @@ class NoteContentFulltextExp extends Expression {
136133 return resultNoteSet ;
137134 }
138135
136+ /**
137+ * Helper method to check if a single word appears as an exact match in text
138+ * @param wordToFind - The word to search for (should be normalized)
139+ * @param text - The text to search in (should be normalized)
140+ * @returns true if the word is found as an exact match (not substring)
141+ */
142+ private exactWordMatch ( wordToFind : string , text : string ) : boolean {
143+ const words = text . split ( / \s + / ) ;
144+ return words . some ( word => word === wordToFind ) ;
145+ }
146+
139147 /**
140148 * Checks if content contains the exact word (with word boundaries) or exact phrase
141149 * This is case-insensitive since content and token are already normalized
@@ -151,9 +159,8 @@ class NoteContentFulltextExp extends Expression {
151159 return normalizedContent . includes ( normalizedToken ) ;
152160 }
153161
154- // For single words, split content into words and check for exact match
155- const words = normalizedContent . split ( / \s + / ) ;
156- return words . some ( word => word === normalizedToken ) ;
162+ // For single words, use exact word matching to avoid substring matches
163+ return this . exactWordMatch ( normalizedToken , normalizedContent ) ;
157164 }
158165
159166 /**
@@ -170,9 +177,8 @@ class NoteContentFulltextExp extends Expression {
170177 // For single-word phrases, use word-boundary matching to avoid substring matches
171178 // e.g., "asd" should not match "asdfasdf"
172179 if ( ! phrase . includes ( ' ' ) ) {
173- // Single word: split into words and check for exact match
174- const words = normalizedContent . split ( / \s + / ) ;
175- return words . some ( word => word === phrase ) ;
180+ // Single word: use exact word matching to avoid substring matches
181+ return this . exactWordMatch ( phrase , normalizedContent ) ;
176182 }
177183
178184 // For multi-word phrases, check if the phrase appears as consecutive words
0 commit comments