Skip to content

Conversation

@joshheald
Copy link
Contributor

Part of: WOOMOB-2109
Merge after #16594

Description

Introduces POSSearchIndexBuilder with:

  • rebuildIndex: clears and re-indexes all eligible products and variations for a site
  • search / searchCount: FTS5 queries with prefix matching and BM25 ranking
  • needsRebuild: detects when the index is stale by comparing entry count to eligible items
  • clearIndex: removes all FTS entries for a site
  • buildFTSQuery: splits search terms on non-alphanumeric characters and wraps each word as a quoted prefix query

Also adds posEligibleProductsRequest on PersistedProduct and posAllVariationsRequest on PersistedProductVariation for index population queries.

Includes comprehensive test suite (21 tests).

Test Steps

  • Run POSSearchIndexBuilderTests — all tests should pass

  • I have considered if this change warrants user-facing release notes and have added them to RELEASE-NOTES.txt if necessary.

Introduces POSSearchIndexBuilder with full-text search capabilities:
- rebuildIndex: clears and re-indexes all eligible products and variations
- search/searchCount: FTS5 queries with prefix matching and BM25 ranking
- needsRebuild: detects when index is stale
- buildFTSQuery: handles multi-word prefix search with special char escaping

Adds posEligibleProductsRequest and posAllVariationsRequest to model
types for index population queries. Includes comprehensive test suite.

Co-Authored-By: Claude Opus 4.5 <[email protected]>
@dangermattic
Copy link
Collaborator

1 Message
📖 This PR is still a Draft: some checks will be skipped.

Generated by 🚫 Danger

@wpmobilebot
Copy link
Collaborator

wpmobilebot commented Jan 30, 2026

App Icon📲 You can test the changes from this Pull Request in WooCommerce iOS Prototype by scanning the QR code below to install the corresponding build.

App NameWooCommerce iOS Prototype
Build Numberpr16595-6bab127
Version24.0
Bundle IDcom.automattic.alpha.woocommerce
Commit6bab127
Installation URL784hq6tij7q6g
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.


/// Returns a request for all non-downloadable variations for a site
static func posAllVariationsRequest(siteID: Int64) -> QueryInterfaceRequest<PersistedProductVariation> {
return PersistedProductVariation
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this use a baseQuery?

)

try db.execute(
sql: "INSERT INTO pos_search_fts (searchable_text, siteID, itemType, itemID, parentProductID) VALUES (?, ?, ?, ?, ?)",
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Double check injection risk

// MARK: - Private

private static func buildFTSQuery(from term: String) -> String {
let words = term.components(separatedBy: CharacterSet.alphanumerics.inverted)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check non-latin languages...

let parentProduct = try PersistedProduct.fetchOne(db, key: ["siteID": siteID, "id": variation.productID])

let attributes = try PersistedProductVariationAttribute
.filter(PersistedProductVariationAttribute.Columns.siteID == siteID)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

perhaps a basequery?

Comment on lines +290 to +291
@Test("search finds variations by attribute")
func test_search_finds_variations_by_attribute() async throws {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a duplicate test?

- Add baseQuery to PersistedProductVariation for consistency with
  PersistedProduct pattern (reviewer comment on posAllVariationsRequest)
- Fix buildFTSQuery to handle CJK ideographs correctly by splitting
  each character individually, matching FTS5 unicode61 tokenizer behavior
  (reviewer comment about non-latin language support)
- Extract tokenize function and add comprehensive tests for tokenization
  covering CJK, Japanese kana/kanji, Korean, Arabic, Hebrew, emoji

Co-Authored-By: Claude Opus 4.5 <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature: POS type: enhancement A request for an enhancement.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants