Repository navigation
[ISSUE-856] test(ai): golden tests for keyword index tokenization, serialization and lifecycle - #877
Conversation
|
Note for reviewers: the red |
|
Update: I cherry-picked the one-line pom fix from #879 into this branch so CI can run independently of that PR's merge. The newly pushed workflow runs need approval to start (same first-run gate as before) — once approved they should go green, as #879's identical change just passed both JDK8 and JDK11 builds. |
…rialization and lifecycle
457deb6 to
db59c97
Compare
|
Branch rebased onto master (now includes the merged #879) — the temporary pom fix is gone from the diff, this PR is back to tests-only. The pushed workflow runs just need approval to start. |
|
Heads-up: this branch hit the same JDK8-only compile issue as #878 (a |
What changes were proposed in this pull request?
Implements #856: golden tests that pin the keyword index's tokenization, serialization format, and lifecycle/retrieval semantics, so that changes to them (a Lucene bump, an edit to query formatting, or the resident keyword index of #825) become visible diffs instead of silent recall shifts.
Added tests (all in
geaflow-ai, following the acceptance criteria of the issue):KeywordTokenizationGoldenTest+tokenization_golden.txt/query_format_golden.txtSearchStore, the instance production shares): lower-casing, hyphen/slash splitting, intra-word dots kept, CJK emitted as single characters.StandardAnalyzer()in the pinned lucene-core 8.11.2 is built with an empty stop-word set (verified via the constructor bytecode), sothe/and/ofare real searchable terms.SearchUtils.formatQuery: excluded characters become spaces and the substringhttpis erased — sohttps://xdegrades tos x(httpscontainshttp).KeywordIndexSerializationGoldenTest+serialized_docs_golden.txtKeywordVectorlands incontentas the wrapperKeywordVector{vec=[a, b]}, multiple vectors joined with the two-space delimiter; vertices carry id/label/content, edges src/dst/label/content.KeywordIndexLifecycleGoldenTestIndexNotFoundExceptionswallowed); indexing after close fails (Lucene'sIndexWriterConfigsharing guard) — the store is single-shot, which is exactly whySessionOperatorrebuilds per query, and what feat(ai): make the keyword search index resident and incremental #825's resident index proposes to change.keywordvectormatches every document and is capped at TopN — the noise a dedicated query representation would remove.GraphAccessor(a hit whose entity is gone, or whose label is unregistered, never surfaces — the Lucene doc survives).学习also recalls a document indexed under习题through the shared character习.theis found by queryingthe.Why golden files (and not plain assertions)?
The recorded expectations were generated against the real analyzer/store on master — including several behaviors nobody had written down (empty stop-word set,
https→s, single-shot lifecycle, wrapper-token pollution). The goldens turn each of these into a decision a future change has to acknowledge.How was this PR tested?
mvn -pl geaflow-ai test— 73 tests, 0 failures (the 14 new ones included).Production verification
Started
GeaFlowMemoryServerfrom this branch (classpath launch) and drove the full HTTP path:/graph/create→/graph/addEntitySchema→/graph/insertEntity× 5 (English, CJK and shared-filler documents) →/query/context→/query/exec→/query/result, across several sessions. Findings:ALPACAmatches likealpaca), CJK queries flow through single-character matching, and the build/close/search rebuild happens per/query/execexactly as the lifecycle test records.quetzal), and even an empty query, each return every entity of the graph; the query text only affects scoring. The root cause is precisely what the goldens pin:KeywordVector.toString()wraps both the indexed content and the query string (SessionOperator.apply→contents.add(v.toString())), so every query carries thekeywordvector/vectokens that every document contains.commonWrapperTokensDoNotCrowdOutExactAnchoringis the executable statement of this fact.GraphSearchStorelayer (locked byemptyQueryFailsTheSearchStore), but the HTTP layer never surfaces it — the wrapper guarantees the parsed query is never empty, so an empty request body degrades to the same full-graph recall rather than an error.Coordination with the resident keyword index PR
Per the issue's constraint, these tests target master's behavior (the PR branch is cut from master, no engine changes). PR #825 will need to update the lifecycle goldens where it changes the single-shot rebuild semantics — the failing golden names the exact behavior that moved. The production verification above should also serve that PR as the before-state of retrieval quality.