MLE-28334 Implement Fragment Option#1937
Open
jonmille wants to merge 1 commit into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
Adds support for the MarkLogic 12.1 fragment search option to fromSearch() and fromSearchDocs(), allowing callers to scope row-pipeline queries to DOCUMENT, PROPERTIES, LOCKS, or ANY fragment types. Also fixes an existing bug in the two-argument fromSearchDocs overload that silently dropped the qualifier name.
Changes:
- Extends
PlanSearchOptionswith aFragmentenum,getFragment()/withFragment(), and corresponding impl/serialization inPlanBuilderBaseImpl(emits"fragment"key with lowercase value). - Fixes
PlanBuilderSubImpl.fromSearchDocs(query, qualifierName)to forwardqualifierNameinstead ofnull. - Adds JUnit 5
RequiresML12Dot1extension and two new test classes (FromSearchWithFragmentTest,FromSearchDocsWithFragmentTest) covering all four fragment types and anexplain()smoke test.
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.
Show a summary per file
| File | Description |
|---|---|
| marklogic-client-api/src/main/java/com/marklogic/client/type/PlanSearchOptions.java | Adds Fragment enum and getFragment/withFragment to the public options interface. |
| marklogic-client-api/src/main/java/com/marklogic/client/impl/PlanBuilderBaseImpl.java | Implements fragment field, constructor, accessors and serialization in PlanSearchOptionsImpl.makeMap(). |
| marklogic-client-api/src/main/java/com/marklogic/client/impl/PlanBuilderSubImpl.java | Bug fix: forwards qualifierName in two-arg fromSearchDocs overload. |
| marklogic-client-api/src/main/java/com/marklogic/client/expression/PlanBuilderBase.java | Updates Javadoc for fromSearchDocs/fromSearch overloads to document fragment scope and 12.1 requirement. |
| marklogic-client-api/src/test/java/com/marklogic/client/test/junit5/RequiresML12Dot1.java | New JUnit 5 ExecutionCondition gating tests on MarkLogic ≥ 12.1. |
| marklogic-client-api/src/test/java/com/marklogic/client/test/rows/FromSearchWithFragmentTest.java | Tests fragment option behavior for fromSearch(). |
| marklogic-client-api/src/test/java/com/marklogic/client/test/rows/FromSearchDocsWithFragmentTest.java | Tests fragment option behavior for fromSearchDocs(). |
Comment on lines
+58
to
+63
| * @param options Specifies scoring options and the fragment type to search. Use | ||
| * {@link PlanBuilder#searchOptions()} with | ||
| * {@link PlanSearchOptions#withFragment(PlanSearchOptions.Fragment)} to control | ||
| * the fragment scope. | ||
| * @return an AccessPlan object | ||
| * @since 8.2.0; requires MarkLogic 12.1 or higher. |
Comment on lines
+48
to
+58
| Fragment getFragment(); | ||
|
|
||
| /** | ||
| * Specifies the type of fragment to search and return. Defaults to {@link Fragment#DOCUMENT} when no option | ||
| * is specified. Applies to both {@code fromSearch()} and {@code fromSearchDocs()}. | ||
| * | ||
| * @param fragment the fragment scope to select | ||
| * @return a new PlanSearchOptions with the fragment set | ||
| * @since 8.2.0; requires MarkLogic 12.1 or higher. | ||
| */ | ||
| PlanSearchOptions withFragment(Fragment fragment); |
Comment on lines
+35
to
+68
| private static final String SETUP_XQUERY = | ||
| "xquery version '1.0-ml';" + | ||
| "let $jsondoc1 := object-node {'AllDataTypes': array-node {object-node {'word':'dog'}, object-node {'rank':1}, object-node {'score':4}}}" + | ||
| "let $jsondoc2 := object-node {'AllDataTypes': array-node {object-node {'word':'cat'}, object-node {'rank':2}, object-node {'score':5}}}" + | ||
| "let $jsondoc3 := object-node {'AllDataTypes': array-node {object-node {'word':'duck'}, object-node {'rank':3}, object-node {'score':6}}}" + | ||
| "return (" + | ||
| "xdmp:document-insert('range-prop-1.json', $jsondoc1, xdmp:default-permissions(), ('elemCol','jsondoc-range','from-search-fragment-test'))," + | ||
| "xdmp:document-insert('range-prop-2.json', $jsondoc2, xdmp:default-permissions(), ('elemCol','jsondoc-range','from-search-fragment-test'))," + | ||
| "xdmp:document-insert('range-prop-3.json', $jsondoc3, xdmp:default-permissions(), ('elemCol','jsondoc-range','from-search-fragment-test'))," + | ||
| "xdmp:document-set-properties('range-prop-1.json', (<my-prop>opticfragmentpropvalue prop1value</my-prop>))," + | ||
| "xdmp:document-set-properties('range-prop-2.json', (<my-prop>opticfragmentpropvalue prop2value</my-prop>))," + | ||
| "xdmp:document-set-properties('range-prop-3.json', (<my-prop>opticfragmentpropvalue prop3value</my-prop>))," + | ||
| "xdmp:lock-acquire('range-prop-1.json', 'exclusive', '0', 'dog rose', xs:unsignedLong(120))," + | ||
| "xdmp:lock-acquire('range-prop-2.json', 'exclusive', '0', 'cat tulip', xs:unsignedLong(120))," + | ||
| "xdmp:lock-acquire('range-prop-3.json', 'exclusive', '0', 'duck lily', xs:unsignedLong(120))" + | ||
| ")"; | ||
|
|
||
| private static final String TEARDOWN_XQUERY = | ||
| "xquery version '1.0-ml';" + | ||
| "for $uri in ('range-prop-1.json', 'range-prop-2.json', 'range-prop-3.json') return xdmp:document-delete($uri)"; | ||
|
|
||
| private static final List<String> EXPECTED_URIS = List.of( | ||
| "range-prop-1.json", "range-prop-2.json", "range-prop-3.json"); | ||
|
|
||
| @BeforeEach | ||
| void setupTest() { | ||
| rowManager.withUpdate(false); | ||
| Common.newEvalClient().newServerEval().xquery(SETUP_XQUERY).evalAs(String.class); | ||
| } | ||
|
|
||
| @AfterEach | ||
| void teardownTest() { | ||
| Common.newEvalClient().newServerEval().xquery(TEARDOWN_XQUERY).evalAs(String.class); | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Add
fragmentoption tofromSearch()andfromSearchDocs()(MLE-28334)Summary
Implements the
fragmentsearch option introduced in MarkLogic 12.1, which controls which fragment types (DOCUMENT,PROPERTIES,LOCKS, orANY) are searched and returned byfromSearch()andfromSearchDocs().Changes
API (
PlanSearchOptions)Fragmentenum with valuesDOCUMENT,ANY,PROPERTIES,LOCKSgetFragment()andwithFragment(Fragment)toPlanSearchOptionsImplementation (
PlanBuilderBaseImpl,PlanBuilderBase,PlanBuilderSubImpl)fragmentfield and updated all-args constructor inPlanSearchOptionsImplgetFragment(),withFragment(), and serialization inmakeMap()(emits lowercase fragment name as"fragment"key)fromSearchDocs(CtsQueryExpr, String, PlanSearchOptions)overloadfromSearchDocs(query, qualifierName)was incorrectly delegating tofromSearchDocs(query, null, null)instead offromSearchDocs(query, qualifierName, null), silently discarding the qualifierTests
RequiresML12Dot1JUnit 5 extension to skip tests on MarkLogic versions below 12.1FromSearchDocsWithFragmentTest— tests all four fragment types (DOCUMENT,LOCKS,PROPERTIES,ANY) viafromSearchDocs(), plus anexplain()smoke testFromSearchWithFragmentTest— equivalent coverage forfromSearch(), including ajoinDocUri()join for document/any fragment cases; notes thatjoinDocUriis unsupported for lock and properties fragment IDs on 12.1Notes
@ExtendWith(RequiresML12Dot1.class)fromSearchDocs()withANYreturns multiple rows per document (one per fragment type), unlikefromSearch()which returns one row per matched fragment IDJira Ticket: https://progresssoftware.atlassian.net/browse/MLE-28334