-
-
Notifications
You must be signed in to change notification settings - Fork 2.3k
Search: Fix word exclusion in client side search #13893
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from all commits
0449e48
dbfbd46
7a8d46e
cfdfda4
80d6ad1
9b06fd5
11d2e2e
6cc4055
ffc193b
7b79f42
a4764b1
234fedc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -171,15 +171,28 @@ const _orderResultsByScoreThenName = (a, b) => { | |||||||||||||||||||||||||||||||||||
* Default splitQuery function. Can be overridden in ``sphinx.search`` with a | ||||||||||||||||||||||||||||||||||||
* custom function per language. | ||||||||||||||||||||||||||||||||||||
* | ||||||||||||||||||||||||||||||||||||
* The regular expression works by splitting the string on consecutive characters | ||||||||||||||||||||||||||||||||||||
* that are not Unicode letters, numbers, underscores, or emoji characters. | ||||||||||||||||||||||||||||||||||||
* This is the same as ``\W+`` in Python, preserving the surrogate pair area. | ||||||||||||||||||||||||||||||||||||
* The `consecutiveLetters` regular expression works by matching consecutive characters | ||||||||||||||||||||||||||||||||||||
* that are Unicode letters, numbers, underscores, or emoji characters. | ||||||||||||||||||||||||||||||||||||
* | ||||||||||||||||||||||||||||||||||||
* The `searchWords` regular expression works by matching a word like structure | ||||||||||||||||||||||||||||||||||||
* that matches the `consecutiveLetters` with or without a leading hyphen '-' which is | ||||||||||||||||||||||||||||||||||||
* used to exclude search terms later on. | ||||||||||||||||||||||||||||||||||||
*/ | ||||||||||||||||||||||||||||||||||||
if (typeof splitQuery === "undefined") { | ||||||||||||||||||||||||||||||||||||
var splitQuery = (query) => | ||||||||||||||||||||||||||||||||||||
query | ||||||||||||||||||||||||||||||||||||
.split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) | ||||||||||||||||||||||||||||||||||||
.filter((term) => term); // remove remaining empty strings | ||||||||||||||||||||||||||||||||||||
var splitQuery = (query) => { | ||||||||||||||||||||||||||||||||||||
const consecutiveLetters = | ||||||||||||||||||||||||||||||||||||
/[\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu; | ||||||||||||||||||||||||||||||||||||
const searchWords = new RegExp( | ||||||||||||||||||||||||||||||||||||
`(${consecutiveLetters.source})|\\s(-${consecutiveLetters.source})`, | ||||||||||||||||||||||||||||||||||||
"gu", | ||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||
return Array.from( | ||||||||||||||||||||||||||||||||||||
query | ||||||||||||||||||||||||||||||||||||
.matchAll(searchWords) | ||||||||||||||||||||||||||||||||||||
.map((results) => results[1] ?? results[2]) // select one of the possible groups (e.g. "word" or "-word"). | ||||||||||||||||||||||||||||||||||||
.filter((term) => term), // remove remaining empty strings. | ||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||
}; | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
/** | ||||||||||||||||||||||||||||||||||||
|
@@ -627,15 +640,18 @@ const Search = { | |||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// ensure that none of the excluded terms is in the search result | ||||||||||||||||||||||||||||||||||||
if ( | ||||||||||||||||||||||||||||||||||||
[...excludedTerms].some( | ||||||||||||||||||||||||||||||||||||
(term) => | ||||||||||||||||||||||||||||||||||||
terms[term] === file | ||||||||||||||||||||||||||||||||||||
|| titleTerms[term] === file | ||||||||||||||||||||||||||||||||||||
|| (terms[term] || []).includes(file) | ||||||||||||||||||||||||||||||||||||
|| (titleTerms[term] || []).includes(file), | ||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||
[...excludedTerms].some((excludedTerm) => { | ||||||||||||||||||||||||||||||||||||
// Both mappings will contain either a single integer or a list of integers. | ||||||||||||||||||||||||||||||||||||
// Converting them to lists makes the comparison more readable. | ||||||||||||||||||||||||||||||||||||
let excludedTermFiles = [].concat(terms[excludedTerm]); | ||||||||||||||||||||||||||||||||||||
let excludedTitleFiles = [].concat(titleTerms[excludedTerm]); | ||||||||||||||||||||||||||||||||||||
return ( | ||||||||||||||||||||||||||||||||||||
excludedTermFiles.includes(file) | ||||||||||||||||||||||||||||||||||||
|| excludedTitleFiles.includes(file) | ||||||||||||||||||||||||||||||||||||
); | ||||||||||||||||||||||||||||||||||||
}) | ||||||||||||||||||||||||||||||||||||
Comment on lines
+643
to
+652
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Do we need this set of I acknowledge that the |
||||||||||||||||||||||||||||||||||||
) | ||||||||||||||||||||||||||||||||||||
break; | ||||||||||||||||||||||||||||||||||||
continue; | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
// select one (max) score for the file. | ||||||||||||||||||||||||||||||||||||
const score = Math.max(...wordList.map((w) => scoreMap.get(file).get(w))); | ||||||||||||||||||||||||||||||||||||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
Excluded Page | ||
============= | ||
|
||
This is a page with the special word penguin. |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
Main Page | ||
========= | ||
|
||
This is the main page of the ``search_exclusion`` test project. | ||
|
||
This document is used as a test fixture to check that search results can be | ||
filtered in the query by specifying excluded terms. | ||
|
||
A term which starts with a hypen will be used as excluded term. | ||
|
||
Include a second page which can be excluded in the search: | ||
:index:`excluded` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I spent some time trying to find an equivalent that is more minimal in terms of lines-of-code / characters-of-code changed.
The following isn't hugely readable -- it's a complex regex, but it essentially enables splits on the
-
character, provided that a lookbehind for whitespace fails.In other words: adds
-
as a split boundary, but only if it is found within a word.