Skip to content
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

Proposal: Modify FTS5Pattern to support a mix of AND and OR. #1666

Open
charlesmchen-bc opened this issue Nov 19, 2024 · 1 comment
Open
Labels

Comments

@charlesmchen-bc
Copy link

FTS5Pattern is great but it's initializers don't cover all cases.

e.g. init?(matchingAnyTokenIn:) covers "foo OR bar" and init?(matchingAllTokensIn:) covers "foo AND bar", but what about: "(foo OR bar) AND other"?

In some cases you want a single pattern that does all of your matching, e.g. ColumnExpression.match(_ pattern: GRDB.FTS5Pattern).

Proposal 1:

extension FTS5Pattern
   static func allOf(_ patterns: [FTS5Pattern]) -> FTS5Pattern 
   static func anyOf(_ patterns: [FTS5Pattern]) -> FTS5Pattern 

"(foo OR bar) AND other" could be expressed like so:

FTS5Pattern.allOf([
   .init(matchingAnyTokenIn:"foo bar"),
   .init(matchingAnyTokenIn:"other"),
])

Proposal 2:
Expose a FTS5Pattern .initializer that takes rawPattern as an escape hatch, so that client code can construct the pattern.

If you consider either proposal a good idea, I could prepare a PR.

Thanks for all of your hard work @groue .

@groue
Copy link
Owner

groue commented Nov 19, 2024

Hello @charlesmchen-bc, and thank you!

If you have access to a database connection, you can combine other patterns with makeFTS5Pattern(rawPattern:forTable:):

func fetchDocuments(_ db: Database) throws -> [Document] {
  let pattern1: FTS5Pattern = ...
  let pattern2: FTS5Pattern = ...
  let combinedRawPattern = "(\(pattern1.rawPattern)) OR (\(pattern2.rawPattern))"
  let combinedPattern = try db.makeFTS5Pattern(rawPattern: combinedRawPattern, forTable: "document")
  return try Document.matching(combinedPattern)
}

As you see, a database connection is required in order to build a FTS5Pattern from a raw string. The goal was to validate FTS5 Column Filters and to fail early, at the pattern creation, instead of failing when the request is executed. Retrospectively, this was probably a mistake, because it is not very handy to have to wait for a connection.

Will you please tell if you can use this technique? If not, we'll relax the api. Your first proposal is interesting as well 👍

@groue groue added the support label Nov 20, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants