Reputation: 1
Below is a XML structure for which I am creating facets. The XML contains two individual document which is loaded individually as example1.xml and example2.xml.
<?xml version="1.0" encoding="UTF-8"?>
<Providers>
<Provider>
<id>1</id>
<Name>Nilabh</Name>
<Products>
<Product>
<Pid>1</Pid>
<ProdName>prd1</ProdName>
<Roles>
<Role>
<RoleCode>R1</RoleCode>
<Specialities>
<Speciality>
<SpecName>S1</SpecName>
</Speciality>
<Speciality>
<SpecName>S2</SpecName>
</Speciality>
</Specialities>
</Role>
<Role>
<RoleCode>R2</RoleCode>
<Specialities>
<Speciality>
<SpecName>S1</SpecName>
</Speciality>
</Specialities>
</Role>
</Roles>
</Product>
<Product>
<Pid>2</Pid>
<ProdName>prd2</ProdName>
<Roles>
<Role>
<RoleCode>R3</RoleCode>
<Specialities>
<Speciality>
<SpecName>S2</SpecName>
</Speciality>
<Speciality>
<SpecName>S3</SpecName>
</Speciality>
</Specialities>
</Role>
<Role>
<RoleCode>R1</RoleCode>
<Specialities>
<Speciality>
<SpecName>S4</SpecName>
</Speciality>
</Specialities>
</Role>
</Roles>
</Product>
</Products>
</Provider>
<Provider>
<id>2</id>
<Name>Nil</Name>
<Products>
<Product>
<Pid>1</Pid>
<ProdName>prd1</ProdName>
<Roles>
<Role>
<RoleCode>R1</RoleCode>
<Specialities>
<Speciality>
<SpecName>S1</SpecName>
</Speciality>
<Speciality>
<SpecName>S3</SpecName>
</Speciality>
</Specialities>
</Role>
<Role>
<RoleCode>R2</RoleCode>
<Specialities>
<Speciality>
<SpecName>S3</SpecName>
</Speciality>
</Specialities>
</Role>
</Roles>
</Product>
<Product>
<Pid>3</Pid>
<ProdName>prd3</ProdName>
<Roles>
<Role>
<RoleCode>R3</RoleCode>
<Specialities>
<Speciality>
<SpecName>S5</SpecName>
</Speciality>
<Speciality>
<SpecName>S3</SpecName>
</Speciality>
</Specialities>
</Role>
<Role>
<RoleCode>R2</RoleCode>
<Specialities>
<Speciality>
<SpecName>S1</SpecName>
</Speciality>
</Specialities>
</Role>
</Roles>
</Product>
</Products>
</Provider>
</Providers>
Below is the XQuery which I use to query with facet. I have defined range indexes on ProdName and SpecName.
import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";
let $options := <options xmlns="http://marklogic.com/appservices/search">
<additional-query>{cts:element-query(xs:QName("ProdName"),"prd3")}</additional-query>
<constraint name="ProdName">
<range type="xs:string" collation="http://marklogic.com/collation/codepoint" facet="true">
<element ns="" name="ProdName"/>
<facet-option>frequency-order</facet-option>
</range>
</constraint>
<constraint name="SpecName">
<range type="xs:string" collation="http://marklogic.com/collation/codepoint" facet="true">
<element ns="" name="SpecName"/>
<facet-option>frequency-order</facet-option>
</range>
</constraint>
<return-results>true</return-results>
<return-facets>true</return-facets>
<debug>true</debug>
</options>
return search:search(" ", $options)
The above query output is as below which shows all entry for facet. However based on my above query I am expecting the "SpecName" Facet should only include entries as [s4(1), s3(1), s5(1)] as this is inside prd3 product, but the output below includes all entries from the result xml. Can someone help me achieve the output as expected.
<search:response snippet-format="snippet" total="2" start="1" page-length="10" xmlns:search="http://marklogic.com/appservices/search">
<search:result index="1" uri="/providers/2.xml" path="fn:doc("/providers/2.xml")" score="2048" confidence="0.1760856" fitness="0.2357023">
<search:snippet>
<search:match path="fn:doc("/providers/2.xml")/Provider/Products/Product[2]">
<search:highlight>prd3</search:highlight>
</search:match>
</search:snippet>
</search:result>
<search:result index="2" uri="/providers/1.xml" path="fn:doc("/providers/1.xml")" score="2048" confidence="0.1760856" fitness="0.2357023">
<search:snippet>
<search:match path="fn:doc("/providers/1.xml")/Provider/Products/Product[3]">
<search:highlight>prd3</search:highlight>
</search:match>
</search:snippet>
</search:result>
<search:facet name="ProdName" type="xs:string">
<search:facet-value name="prd1" count="2">prd1</search:facet-value>
<search:facet-value name="prd3" count="2">prd3</search:facet-value>
<search:facet-value name="prd2" count="1">prd2</search:facet-value>
<search:facet-value name="prd5" count="1">prd5</search:facet-value>
</search:facet>
<search:facet name="SpecName" type="xs:string">
<search:facet-value name="S1" count="2">S1</search:facet-value>
<search:facet-value name="S3" count="2">S3</search:facet-value>
<search:facet-value name="S2" count="1">S2</search:facet-value>
<search:facet-value name="S4" count="1">S4</search:facet-value>
<search:facet-value name="S5" count="1">S5</search:facet-value>
<search:facet-value name="S6" count="1">S6</search:facet-value>
</search:facet>
<search:qtext>
</search:qtext>
<search:report id="SEARCH-FLWOR">(cts:search(fn:collection(), cts:and-query(cts:element-query(fn:QName("","ProdName"), cts:word-query("prd3", ("lang=en"), 1), ()), ()), ("score-logtfidf","faceted",cts:score-order("descending")), 1))[1 to 10]</search:report>
<search:metrics>
<search:query-resolution-time>PT0.596S</search:query-resolution-time>
<search:facet-resolution-time>PT0.1S</search:facet-resolution-time>
<search:snippet-resolution-time>PT0.047S</search:snippet-resolution-time>
<search:total-time>PT1.275S</search:total-time>
</search:metrics>
</search:response>
My requirement is as if some one search for ProdName: prd1 and RoleCode:R1 then Facet SpecName should show output as S1(2), S2(1), S3(1). Can you guide me how to get this output.
Regards, Nilabh
Upvotes: 0
Views: 218
Reputation: 3138
There are multiple steps to fulfil your requirements:
Run following search script from ML query console:
search:search("((ProdName:prd1) AND (RoleCode:R1))", $options)
which will give you expected output:
<search:response snippet-format="snippet" total="1" start="1" page-length="10" xmlns:search="http://marklogic.com/appservices/search">
<search:result></search:result>
<search:facet name="ProdName" type="xs:string">
<search:facet-value name="prd1" count="2">prd1</search:facet-value>
</search:facet>
<search:facet name="RoleCode" type="xs:string">
<search:facet-value name="R1" count="2">R1</search:facet-value>
<search:facet-value name="R2" count="2">R2</search:facet-value>
</search:facet>
<search:facet name="SpecName" type="xs:string">
<search:facet-value name="S1" count="2">S1</search:facet-value>
<search:facet-value name="S2" count="1">S2</search:facet-value>
<search:facet-value name="S3" count="1">S3</search:facet-value>
</search:facet>
<search:qtext>((ProdName:prd1) AND (RoleCode:R1))</search:qtext>
<search:report id="SEARCH-FLWOR">(cts:search(fn:collection(), cts:and-query((cts:element-range-query(fn:QName("","ProdName"), "=", "prd1", ("collation=http://marklogic.com/collation/"), 1), cts:element-range-query(fn:QName("","RoleCode"), "=", "R1", ("collation=http://marklogic.com/collation/"), 1)), ()), ("score-logtfidf","faceted",cts:score-order("descending")), 1))[1 to 10]</search:report>
<search:metrics>
<search:query-resolution-time>PT0.088S</search:query-resolution-time>
<search:facet-resolution-time>PT0.198S</search:facet-resolution-time>
<search:snippet-resolution-time>PT0.016S</search:snippet-resolution-time>
<search:total-time>PT0.389S</search:total-time>
</search:metrics>
</search:response>
Upvotes: 0
Reputation: 20414
You are trying to get facet results per product, but store all products within one fragment. I think you are better off splitting the large XML at product level..
HTH!
Upvotes: 1