Pre-built custom search constraints that go beyond what the MarkLogic REST API provides OOTB
Installation depends on the MarkLogic Package Manager:
$ mlpm install ml-constraints --save
$ mlpm deploy
This custom constraint can be wrapped around any existing search constraint to provide alternative facet value counts. By excluding queries from the constraint itself, facet values will include alternative values, and matching counts, while still respecting constraints from other facets.
Take an existing search constraint in your REST api query options, and put the following after the open tag <constraint name="myconstraint">
:
<custom>
<parse apply="parse-structured" ns="http://marklogic.com/others-where-constraint" at="/ext/mlpm_modules/ml-constraints/others-where-constraint.xqy"/>
<start-facet apply="start" ns="http://marklogic.com/others-where-constraint" at="/ext/mlpm_modules/ml-constraints/others-where-constraint.xqy"/>
<finish-facet apply="finish" ns="http://marklogic.com/others-where-constraint" at="/ext/mlpm_modules/ml-constraints/others-where-constraint.xqy"/>
</custom>
<annotation>
Put the following before the closing tag </constraint>
:
</annotation>
E.g. this:
<constraint name="myconstraint">
<range collation="http://marklogic.com/collation/" type="xs:string" facet="true">
<element ns="http://some-ns.com/example" name="myexample"/>
<facet-option>frequency-order</facet-option>
<facet-option>descending</facet-option>
<facet-option>limit=10</facet-option>
</range>
</constraint>
would become:
<constraint name="myconstraint">
<custom>
<parse apply="parse-structured" ns="http://marklogic.com/others-where-constraint" at="/ext/mlpm_modules/ml-constraints/others-where-constraint.xqy"/>
<start-facet apply="start" ns="http://marklogic.com/others-where-constraint" at="/ext/mlpm_modules/ml-constraints/others-where-constraint.xqy"/>
<finish-facet apply="finish" ns="http://marklogic.com/others-where-constraint" at="/ext/mlpm_modules/ml-constraints/others-where-constraint.xqy"/>
</custom>
<annotation>
<range collation="http://marklogic.com/collation/" type="xs:string" facet="true">
<element ns="http://some-ns.com/example" name="myexample"/>
<facet-option>frequency-order</facet-option>
<facet-option>descending</facet-option>
<facet-option>limit=10</facet-option>
</range>
</annotation>
</constraint>
EQ
comparison, e.g. myconstraint:somevalue
, and not myconstraint GT somevalue
(RFE has been filed)This custom constraint can be wrapped around any existing search constraint to apply an additional query that only applies to that search constraint (and its facet values).
Take an existing search constraint in your REST api query options, and put the following after the open tag <constraint name="myconstraint">
:
<custom>
<parse apply="parse-structured" ns="http://marklogic.com/additional-query-constraint" at="/ext/mlpm_modules/ml-constraints/additional-query-constraint.xqy"/>
<start-facet apply="start" ns="http://marklogic.com/additional-query-constraint" at="/ext/mlpm_modules/ml-constraints/additional-query-constraint.xqy"/>
<finish-facet apply="finish" ns="http://marklogic.com/additional-query-constraint" at="/ext/mlpm_modules/ml-constraints/additional-query-constraint.xqy"/>
</custom>
<annotation>
Put the following before the closing tag </constraint>
:
<additional-query>
</additional-query>
</annotation>
Inside additional query you can insert any serialized cts:query, for instance a cts:collection-query:
<cts:collection-query xmlns:cts="http://marklogic.com/cts">
<cts:uri>examples</cts:uri>
</cts:collection-query>
E.g. this:
<constraint name="myconstraint">
<range collation="http://marklogic.com/collation/" type="xs:string" facet="true">
<element ns="http://some-ns.com/example" name="myexample"/>
<facet-option>frequency-order</facet-option>
<facet-option>descending</facet-option>
<facet-option>limit=10</facet-option>
</range>
</constraint>
would become:
<constraint name="myconstraint">
<custom>
<parse apply="parse-structured" ns="http://marklogic.com/additional-query-constraint" at="/ext/mlpm_modules/ml-constraints/additional-query-constraint.xqy"/>
<start-facet apply="start" ns="http://marklogic.com/additional-query-constraint" at="/ext/mlpm_modules/ml-constraints/additional-query-constraint.xqy"/>
<finish-facet apply="finish" ns="http://marklogic.com/additional-query-constraint" at="/ext/mlpm_modules/ml-constraints/additional-query-constraint.xqy"/>
</custom>
<annotation>
<range collation="http://marklogic.com/collation/" type="xs:string" facet="true">
<element ns="http://some-ns.com/example" name="myexample"/>
<facet-option>frequency-order</facet-option>
<facet-option>descending</facet-option>
<facet-option>limit=10</facet-option>
</range>
<additional-query>
<cts:collection-query xmlns:cts="http://marklogic.com/cts">
<cts:uri>examples</cts:uri>
</cts:collection-query>
</additional-query>
</annotation>
</constraint>
EQ
comparison, e.g. myconstraint:somevalue
, and not myconstraint GT somevalue
(RFE has been filed)This custom constraint can be wrapped around any existing range constraint to apply dynamic buckets, based on min/max or number of buckets.
Take an existing range constraint in your REST api query options, and put the following after the open tag <constraint name="myconstraint">
:
<constraint name="myconstraint">
<custom facet="true">
<parse apply="parse-structured" ns="http://marklogic.com/dynamic-buckets-constraint" at="/ext/mlpm_modules/ml-constraints/dynamic-buckets-constraint.xqy"/>
<start-facet apply="start" ns="http://marklogic.com/dynamic-buckets-constraint" at="/ext/mlpm_modules/ml-constraints/dynamic-buckets-constraint.xqy"/>
<finish-facet apply="finish" ns="http://marklogic.com/dynamic-buckets-constraint" at="/ext/mlpm_modules/ml-constraints/dynamic-buckets-constraint.xqy"/>
</custom>
<annotation>
Put the following before the closing tag </constraint>
:
<config xmlns="http://marklogic.com/dynamic-buckets-constraint">
<min>1996</min>
<max>2016</max>
</config>
</annotation>
</constraint>
Inside additional query you can insert any serialized cts:query, for instance a cts:collection-query:
E.g. this:
<constraint name="myconstraint">
<range type="xs:date" facet="true">
<facet-option>item-order</facet-option>
<facet-option>ascending</facet-option>
<element ns="some-ns.com/example" name="date"/>
</range>
</constraint>
would become:
<constraint name="myconstraint">
<custom facet="true">
<parse apply="parse-structured" ns="http://marklogic.com/dynamic-buckets-constraint" at="/ext/mlpm_modules/ml-constraints/dynamic-buckets-constraint.xqy"/>
<start-facet apply="start" ns="http://marklogic.com/dynamic-buckets-constraint" at="/ext/mlpm_modules/ml-constraints/dynamic-buckets-constraint.xqy"/>
<finish-facet apply="finish" ns="http://marklogic.com/dynamic-buckets-constraint" at="/ext/mlpm_modules/ml-constraints/dynamic-buckets-constraint.xqy"/>
</custom>
<annotation>
<range type="xs:date" facet="true">
<facet-option>item-order</facet-option>
<facet-option>ascending</facet-option>
<element ns="some-ns.com/example" name="date"/>
</range>
<config xmlns="http://marklogic.com/dynamic-buckets-constraint">
<min>1996</min>
<max>2016</max>
</config>
</annotation>
</constraint>
Note: min/max are only used for xs:date range constraints, and represent minimum year, and maximum year for which buckets are supposed to be generated. If the actual minimum or maximum goes beyond, first and/or last bucket name is prepended with the ≤ resp ≥ character. All other range constraint data types currently ignore min/max and take nr-buckets instead. A fixed number of buckets (defaulting to 10) is created, evenly spread between actual min and max.
This custom constraint can be wrapped around any existing search constraint to apply grouping of values leveraging value-match patterns.
Take an existing search constraint in your REST api query options, and put the following after the open tag <constraint name="myconstraint">
:
<custom>
<parse apply="parse-structured" ns="http://marklogic.com/grouping-constraint" at="/ext/mlpm_modules/ml-constraints/grouping-constraint.xqy"/>
<start-facet apply="start" ns="http://marklogic.com/grouping-constraint" at="/ext/mlpm_modules/ml-constraints/grouping-constraint.xqy"/>
<finish-facet apply="finish" ns="http://marklogic.com/grouping-constraint" at="/ext/mlpm_modules/ml-constraints/grouping-constraint.xqy"/>
</custom>
<annotation>
Put the following before the closing tag </constraint>
:
<config>
<show-remainder label="Other"/>
</config>
</annotation>
Inside config you can insert groups, and provide multiple match patterns for each as follows:
<group label="A-M">
<match pattern="A*"/>
<match pattern="B*"/>
<match pattern="C*"/>
<match pattern="D*"/>
<match pattern="E*"/>
<match pattern="F*"/>
<match pattern="G*"/>
<match pattern="H*"/>
<match pattern="I*"/>
<match pattern="J*"/>
<match pattern="K*"/>
<match pattern="L*"/>
<match pattern="M*"/>
</group>
<group label="N-Z">
<match pattern="N*"/>
<match pattern="O*"/>
<match pattern="P*"/>
<match pattern="Q*"/>
<match pattern="R*"/>
<match pattern="S*"/>
<match pattern="T*"/>
<match pattern="U*"/>
<match pattern="V*"/>
<match pattern="W*"/>
<match pattern="X*"/>
<match pattern="Y*"/>
<match pattern="Z*"/>
</group>
IMPORTANT: move facet-options related to fragment scoping over to the custom tag!
E.g. this:
<constraint name="myconstraint">
<range collation="http://marklogic.com/collation/" type="xs:string" facet="true">
<element ns="http://some-ns.com/example" name="myexample"/>
<facet-option>frequency-order</facet-option>
<facet-option>descending</facet-option>
<facet-option>limit=10</facet-option>
<facet-option>properties</facet-option>
</range>
</constraint>
would become:
<constraint name="myconstraint">
<custom>
<parse apply="parse-structured" ns="http://marklogic.com/grouping-constraint" at="/ext/mlpm_modules/ml-constraints/grouping-constraint.xqy"/>
<start-facet apply="start" ns="http://marklogic.com/grouping-constraint" at="/ext/mlpm_modules/ml-constraints/grouping-constraint.xqy"/>
<finish-facet apply="finish" ns="http://marklogic.com/grouping-constraint" at="/ext/mlpm_modules/ml-constraints/grouping-constraint.xqy"/>
<!-- moved this facet-option to here to make sure correct fragments are used -->
<facet-option>properties</facet-option>
</custom>
<annotation>
<range collation="http://marklogic.com/collation/" type="xs:string" facet="true">
<element ns="http://some-ns.com/example" name="myexample"/>
<facet-option>frequency-order</facet-option>
<facet-option>descending</facet-option>
<facet-option>limit=10</facet-option>
<!-- moved fragment scope facet-option to custom tag -->
</range>
<config>
<group label="A-M">
<match pattern="A*"/>
<match pattern="B*"/>
<match pattern="C*"/>
<match pattern="D*"/>
<match pattern="E*"/>
<match pattern="F*"/>
<match pattern="G*"/>
<match pattern="H*"/>
<match pattern="I*"/>
<match pattern="J*"/>
<match pattern="K*"/>
<match pattern="L*"/>
<match pattern="M*"/>
</group>
<group label="N-Z">
<match pattern="N*"/>
<match pattern="O*"/>
<match pattern="P*"/>
<match pattern="Q*"/>
<match pattern="R*"/>
<match pattern="S*"/>
<match pattern="T*"/>
<match pattern="U*"/>
<match pattern="V*"/>
<match pattern="W*"/>
<match pattern="X*"/>
<match pattern="Y*"/>
<match pattern="Z*"/>
</group>
<show-remainder label="Other"/>
</config>
</annotation>
</constraint>
EQ
comparison, e.g. myconstraint:somevalue
, and not myconstraint GT somevalue
(RFE has been filed)