From 49ae6fefa31e93e26fe1a8d0379eb2658c545269 Mon Sep 17 00:00:00 2001 From: Rob Rudin Date: Fri, 22 Nov 2024 11:57:10 -0500 Subject: [PATCH] MLE-17044 Added trueQuery, falseQuery, and operatorState These were all oversights in `StructuredQueryBuilder`. --- .../client/query/StructuredQueryBuilder.java | 70 +++++++++++++++++++ .../client/test/StructuredSearchTest.java | 50 +++++++++++++ 2 files changed, 120 insertions(+) diff --git a/marklogic-client-api/src/main/java/com/marklogic/client/query/StructuredQueryBuilder.java b/marklogic-client-api/src/main/java/com/marklogic/client/query/StructuredQueryBuilder.java index fb80e4327..3787433ef 100644 --- a/marklogic-client-api/src/main/java/com/marklogic/client/query/StructuredQueryBuilder.java +++ b/marklogic-client-api/src/main/java/com/marklogic/client/query/StructuredQueryBuilder.java @@ -336,6 +336,39 @@ public StructuredQueryDefinition andNot(StructuredQueryDefinition positive, Stru return new AndNotQuery(positive, negative); } + /** + * Defines a "true" query that selects all documents. + * + * @since 7.1.0 + * @return the StructuredQueryDefinition for the "true" query. + */ + public StructuredQueryDefinition trueQuery() { + return new TrueQuery(); + } + + /** + * Defines a "true" query that selects all documents. + * + * @since 7.1.0 + * @return the StructuredQueryDefinition for the "true" query. + */ + public StructuredQueryDefinition falseQuery() { + return new FalseQuery(); + } + + /** + * Define a new operator state; see https://docs.marklogic.com/guide/search-dev/structured-query#id_45570 for + * more information. + * + * @param operatorName The name of a custom runtime configuration operator defined by the query option. + * @param stateName The name of a state recognized by this operator. + * @since 7.1.0 + * @return the StructuredQueryDefinition for the operator state. + */ + public StructuredQueryDefinition operatorState(String operatorName, String stateName) { + return new OperatorState(operatorName, stateName); + } + /** * Defines a NEAR query over the list of query definitions * with default parameters. @@ -1289,6 +1322,43 @@ public void innerSerialize(XMLStreamWriter serializer) throws XMLStreamException } } + protected class TrueQuery extends AbstractStructuredQuery { + @Override + public void innerSerialize(XMLStreamWriter serializer) throws XMLStreamException { + serializer.writeEmptyElement(SEARCH_API_NS, "true-query"); + } + } + + protected class FalseQuery extends AbstractStructuredQuery { + @Override + public void innerSerialize(XMLStreamWriter serializer) throws XMLStreamException { + serializer.writeEmptyElement(SEARCH_API_NS, "false-query"); + } + } + + protected class OperatorState extends AbstractStructuredQuery { + + private final String operatorName; + private final String stateName; + public OperatorState(String operatorName, String stateName) { + super(); + this.operatorName = operatorName; + this.stateName = stateName; + } + + @Override + public void innerSerialize(XMLStreamWriter serializer) throws XMLStreamException { + writeSearchElement(serializer, "operator-state"); + writeSearchElement(serializer, "operator-name"); + serializer.writeCharacters(operatorName); + serializer.writeEndElement(); + writeSearchElement(serializer, "state-name"); + serializer.writeCharacters(stateName); + serializer.writeEndElement(); + serializer.writeEndElement(); + } + } + protected class AndNotQuery extends AbstractStructuredQuery { private StructuredQueryDefinition positive; diff --git a/marklogic-client-api/src/test/java/com/marklogic/client/test/StructuredSearchTest.java b/marklogic-client-api/src/test/java/com/marklogic/client/test/StructuredSearchTest.java index 40d608a4d..6571aa05c 100644 --- a/marklogic-client-api/src/test/java/com/marklogic/client/test/StructuredSearchTest.java +++ b/marklogic-client-api/src/test/java/com/marklogic/client/test/StructuredSearchTest.java @@ -14,13 +14,17 @@ import com.marklogic.client.io.StringHandle; import com.marklogic.client.query.*; import com.marklogic.client.util.EditableNamespaceContext; +import org.jdom2.Namespace; +import org.jdom2.input.SAXBuilder; import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.xml.sax.SAXException; import java.io.IOException; +import java.io.StringReader; import java.util.concurrent.atomic.AtomicInteger; import static org.custommonkey.xmlunit.XMLAssert.assertXMLEqual; @@ -28,11 +32,57 @@ public class StructuredSearchTest { + private QueryManager queryManager; + private StructuredQueryBuilder queryBuilder; + @BeforeAll public static void beforeClass() { Common.connect(); } + @BeforeEach + void setup() { + queryManager = Common.client.newQueryManager(); + queryBuilder = queryManager.newStructuredQueryBuilder(); + } + + @Test + void trueQuery() { + long total = queryManager.search(queryBuilder.and( + queryBuilder.trueQuery(), + queryBuilder.collection("zipcode") + ), new SearchHandle()).getTotalResults(); + assertEquals(2, total, "Expecting 2 documents in the zipcode collection, and the trueQuery should not affect that."); + + total = queryManager.search(queryBuilder.trueQuery(), new SearchHandle()).getTotalResults(); + assertTrue(total > 2, "Expecting all documents to be returned, which should be more than the 2 in the " + + "zipcode collection. Actual count: " + total); + } + + @Test + void falseQuery() { + long total = queryManager.search(queryBuilder.and( + queryBuilder.falseQuery(), + queryBuilder.collection("zipcode") + ), new SearchHandle()).getTotalResults(); + assertEquals(0, total, "Expecting 0 documents due to the false query."); + + total = queryManager.search(queryBuilder.falseQuery(), new SearchHandle()).getTotalResults(); + assertEquals(0, total, "A false-query should return zero documents."); + } + + @Test + void operatorState() throws Exception { + StructuredQueryDefinition query = queryBuilder.operatorState("sort", "date"); + String xml = query.serialize(); + + org.jdom2.Document doc = new SAXBuilder().build(new StringReader(xml)); + Namespace ns = Namespace.getNamespace("http://marklogic.com/appservices/search"); + org.jdom2.Element operatorState = doc.getRootElement().getChild("operator-state", ns); + assertEquals("sort", operatorState.getChildText("operator-name", ns)); + assertEquals("date", operatorState.getChildText("state-name", ns)); + } + @Test public void testStructuredSearch() { QueryManager queryMgr = Common.client.newQueryManager();