GithubHelp home page GithubHelp logo

peetkes / ml-constraints Goto Github PK

View Code? Open in Web Editor NEW

This project forked from grtjn/ml-constraints

0.0 2.0 0.0 27 KB

Custom MarkLogic constraints that go beyond what Search API provides out of the box

License: Apache License 2.0

XQuery 100.00%
xquery marklogic multi-select faceted-search custom-constraints

ml-constraints's Introduction

ml-constraints

Pre-built custom search constraints that go beyond what the MarkLogic REST API provides OOTB

Install

Installation depends on the MarkLogic Package Manager:

$ mlpm install ml-constraints --save
$ mlpm deploy

additional-query-constraint

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).

Usage

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>

Known issues

  • This constraint only implements a parse-structured method, and is therefore only supported by the REST api. The parse-string approach does not pass through the full query options, which is essential in this case
  • Custom constraints currently only support EQ comparison, e.g. myconstraint:somevalue, and not myconstraint GT somevalue (RFE has been filed)
  • Due to a bug/limitation of the REST api parse-structured-style constraint are not supported by /v1/suggest (Bug has been filed)

dynamic-buckets-constraint

This custom constraint can be wrapped around any existing range constraint to apply dynamic buckets, based on min/max or number of buckets.

Usage

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.

grouping-constraint

This custom constraint can be wrapped around any existing search constraint to apply grouping of values leveraging value-match patterns.

Usage

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>

Known issues

  • This constraint only implements a parse-structured method, and is therefore only supported by the REST api. The parse-string approach does not pass through the full query options, which is essential in this case
  • Custom constraints currently only support EQ comparison, e.g. myconstraint:somevalue, and not myconstraint GT somevalue (RFE has been filed)
  • Due to a bug/limitation of the REST api parse-structured-style constraint are not supported by /v1/suggest (Bug has been filed)

parallel-select-constraint

This custom constraint can be wrapped around any existing search constraint to apply parallel selection of facets.

Usage

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/parallel-select-constraint" at="/ext/mlpm_modules/ml-constraints/parallel-select-constraint.xqy"/>
  <start-facet apply="start" ns="http://marklogic.com/parallel-select-constraint" at="/ext/mlpm_modules/ml-constraints/parallel-select-constraint.xqy"/>
  <finish-facet apply="finish" ns="http://marklogic.com/parallel-selecty-constraint" at="/ext/mlpm_modules/ml-constraints/parallel-select-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/parallel-select-constraint" at="/ext/mlpm_modules/ml-constraints/parallel-select-constraint.xqy"/>
    <start-facet apply="start" ns="http://marklogic.com/parallel-select-constraint" at="/ext/mlpm_modules/ml-constraints/parallel-select-constraint.xqy"/>
    <finish-facet apply="finish" ns="http://marklogic.com/parallel-selecty-constraint" at="/ext/mlpm_modules/ml-constraints/parallel-select-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>

In the UI you have to take care of the multi select bit for this facet.

ml-constraints's People

Contributors

grtjn avatar peetkes avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.