feat(core): add CJK substring search support - #1376
Conversation
Signed-off-by: Aryan Pardeshi <aryanpardeshi606@gmail.com>
Signed-off-by: Aryan Pardeshi <aryanpardeshi606@gmail.com>
Signed-off-by: Aryan Pardeshi <aryanpardeshi606@gmail.com>
Signed-off-by: Aryan Pardeshi <aryanpardeshi606@gmail.com>
Signed-off-by: Aryan Pardeshi <aryanpardeshi606@gmail.com>
Signed-off-by: Aryan Pardeshi <aryanpardeshi606@gmail.com>
Signed-off-by: Aryan Pardeshi <aryanpardeshi606@gmail.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 9152cf35a1
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| for match in RELAXATION_CJK_PATTERN.finditer(field): | ||
| tokens.extend(cjk_bigram_tokens(match.group(0))) |
There was a problem hiding this comment.
Preserve gaps between independently tokenized CJK runs
When CJK runs are separated by Latin text, punctuation, or a field boundary, appending every run's bigrams without a separator makes their tokens adjacent in the FTS stream. For example, cjk_search_tokens("适者 latin 者生存") produces 适者 者生 生存, so both SQLite and PostgreSQL incorrectly satisfy the phrase query for the contiguous substring 适者生存; the regression test avoids this by manually inserting a gap token rather than exercising this function. Insert a nonmatching positional separator between runs and fields so only genuinely contiguous text satisfies adjacency.
Useful? React with 👍 / 👎.
| lexical_condition = ( | ||
| f"({lexical_condition} OR search_index.search_tokens MATCH :cjk_text)" | ||
| ) |
There was a problem hiding this comment.
Keep non-CJK operands in mixed CJK matches
When a query mixes CJK and non-CJK terms under the default AND semantics (for example, 适者生存 backendmarker or the explicit 适者生存 AND backendmarker), this top-level OR lets any row matching only the CJK phrase through even if backendmarker is absent. The analogous PostgreSQL condition has the same behavior; the current test's “CJK only” row happens to contain nonadjacent auxiliary tokens, so it does not cover an exact CJK-only match. Combine the auxiliary phrase with the remaining query operands according to the original Boolean semantics instead of treating it as an alternative to the whole query.
Useful? React with 👍 / 👎.
Summary
Closes #1294.
basic-memory reindex --full --search.Verification
An overlapping maintainer PR (#1373) is currently open for this issue. Please compare implementations and close/supersede whichever branch is not selected.