Nilabh Sagar
Nilabh Sagar

Reputation: 1

Facets in MarkLogic not coming as expected

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 Input:

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

Output:

<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

Answers (2)

Navin Rawat
Navin Rawat

Reputation: 3138

There are multiple steps to fulfil your requirements:

  1. On your database set 'Fragment Parents' as 'Products'.
  2. Create Element range index on 'RoleCode', 'ProdName', and 'SpecName'
  3. Insert your document into ML database.
  4. 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

grtjn
grtjn

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

Related Questions