Marklogic 关于增强cts:query中相应的节点

需求:

这个需求是这样的:对于双引号的Phrase需要进行精确的查询。例如:

Query text为:

Marklogic is “enterprise NoSql” solution.

Search:parse结果:

我们发现在做完search:parse后得到:

search:parse('Marklogic is "enterprise NoSql"solution')

return

<cts:and-query strength="20" qtextjoin=""qtextgroup="( )" xmlns:cts="http://marklogic.com/cts">

  <cts:word-queryqtextref="cts:text">

    <cts:text>Marklogic</cts:text>

 </cts:word-query>

  <cts:and-querystrength="20" qtextjoin="" qtextgroup="( )">

    <cts:word-queryqtextref="cts:text">

      <cts:text>is</cts:text>

   </cts:word-query>

    <cts:and-querystrength="20" qtextjoin="" qtextgroup="( )">

     <cts:word-query qtextpre="&quot;"qtextref="cts:text" qtextpost="&quot;">

                <cts:text>enterprise NoSql</cts:text>

      </cts:word-query>

     <cts:word-query qtextref="cts:text">

                <cts:text>solution</cts:text>

     </cts:word-query>

   </cts:and-query>

 </cts:and-query>

</cts:and-query>

我们看到”enterpriseNoSql”作为一个phrase进行查询。是没有问题的。

问题QueryText:

Marklogic is “document” solution

Search:parse结果:

我们发现在做完search:parse后得到:

search:parse('Marklogic is "document" solution')

<cts:and-query strength="20"qtextjoin="" qtextgroup="( )"xmlns:cts="http://marklogic.com/cts">

  <cts:word-queryqtextref="cts:text">

   <cts:text>Marklogic</cts:text>

 </cts:word-query>

  <cts:and-querystrength="20" qtextjoin="" qtextgroup="( )">

    <cts:word-queryqtextref="cts:text">

     <cts:text>is</cts:text>

   </cts:word-query>

    <cts:and-querystrength="20" qtextjoin="" qtextgroup="( )">

      <cts:word-queryqtextpre="&quot;" qtextref="cts:text"qtextpost="&quot;">

                <cts:text>document</cts:text>

     </cts:word-query>

     <cts:word-query qtextref="cts:text">

                <cts:text>solution</cts:text>

     </cts:word-query>

   </cts:and-query>

  </cts:and-query>

</cts:and-query>

问题:

你会发现document转化为的word-query与其它的word-query基本一致。这里就会有潜在的问题了。

如果当下我们的searchoption设置的是stemmed。那么该document查询过程中就会使用到了stemmed。

因此你会得到诸如documents,document的变体查询结果。这个是不允许的。因为用户想要对双引号内的term做精确查询。

方案:

有上面获得的parse结果来看,思路就是:如果这个word-query有前置,及后置双引号,那么我们需要人工干预,给该word-query加一个unstemmedoption.

       <cts:word-query qtextpre="&quot;" qtextref="cts:text"qtextpost="&quot;">

                                                <cts:text>document</cts:text>

     </cts:word-query>

变形后:

    <cts:word-queryqtextpre="&quot;" qtextref="cts:text"qtextpost="&quot;">

     <cts:text>document</cts:text>

      <cts:option>unstemmed</cts:option>

   </cts:word-query>

 

具体实现:

1:使用search:prase

获得cts:query解析xml结构对象,以便于处理其中的word-query对象。

2:使用xdmp:set

实行过程中,使用了xdmp:set毫无疑问是用来处理变量的。当我们加入设置了新的option,需要把该变换影射到cts:query变量上

3:使用search:resolve

用它来执行你的结构化cts:query (search:search用来执行querytext)


源代码:

直接顺序替代。发现目标---〉替换目标。整个迭代过程由orginalelement进行。

 

declare namespacects="http://marklogic.com/cts";

 

declare function local:copy-replace($elementas element()) { 

      

  if ($element/self::cts:word-query)  (判断替换条件)

  then

  (

    if($element/@qtextpre="&quot;"and  $element/@qtextpost="&quot;")then

       (

         <root>{

           cts:and-query((

           cts:or-query((

           cts:element-word-query(fn:QName("http://www.wolterskluver.com/namespace/meta","DocTitle"),$element//cts:text/text(),("unstemmed","case-insensitive"),16),

           cts:element-query(fn:QName("http://www.wolterskluver.com/namespace/meta","Meta"),cts:word-query($element//cts:text/text(),("unstemmed","case-insensitive"),2)),          

           cts:word-query($element//cts:text/text(),("unstemmed","case-insensitive"),1)

         ))

         ))

         }</root>/*

       )

    else

       (

         <root>{

           cts:and-query((

           cts:or-query((

           cts:element-word-query(fn:QName("http://www.wolterskluver.com/namespace/meta","DocTitle"),$element//cts:text/text(), "case-insensitive",16),

           cts:element-query(fn:QName("http://www.wolterskluver.com/namespace/meta","Meta"),cts:word-query($element//cts:text/text(),"case-insensitive",2)),          

           cts:word-query($element//cts:text/text(),"case-insensitive",1)

         ))

         ))

         }</root>/*

       )

  )

  else element {node-name($element)} 

              {$element/@*,

                for $childin $element/node() 

                return if ($child instance of element()) 

                       then local:copy-replace($child

                       else $child 

              

}; 

 

let $query:=search:parse('abc "SUPPLEMENT" ABC')

 

return

(

local:copy-replace($query),

search:resolve(local:copy-replace($query))

)

 

结果输出:

<?xml version="1.0" encoding="UTF-8"?>

<cts:and-query strength="20"qtextjoin="" qtextgroup="( )"xmlns:cts="http://marklogic.com/cts">

  <cts:and-query>

    <cts:or-query>

      <cts:element-word-queryweight="16">

                <cts:elementxmlns:_1="http://www.wolterskluver.com/namespace/meta">_1:DocTitle</cts:element>

                <cts:textxml:lang="en">abc</cts:text>

                <cts:option>case-insensitive</cts:option>

     </cts:element-word-query>

      <cts:element-query>

                <cts:elementxmlns:_1="http://www.wolterskluver.com/namespace/meta">_1:Meta</cts:element>

                <cts:word-queryweight="2">

                  <cts:textxml:lang="en">abc</cts:text>

                 <cts:option>case-insensitive</cts:option>

                </cts:word-query>

     </cts:element-query>

      <cts:word-query>

                <cts:textxml:lang="en">abc</cts:text>

                <cts:option>case-insensitive</cts:option>

     </cts:word-query>

    </cts:or-query>

  </cts:and-query>

  <cts:and-querystrength="20" qtextjoin="" qtextgroup="( )">

   <cts:and-query>

     <cts:or-query>

                <cts:element-word-queryweight="16">

                  <cts:element xmlns:_1="http://www.wolterskluver.com/namespace/meta">_1:DocTitle</cts:element>

                  <cts:textxml:lang="en">SUPPLEMENT</cts:text>

                 <cts:option>case-insensitive</cts:option>

                 <cts:option>unstemmed</cts:option>

                </cts:element-word-query>

                <cts:element-query>

                  <cts:elementxmlns:_1="http://www.wolterskluver.com/namespace/meta">_1:Meta</cts:element>

                  <cts:word-query weight="2">

                    <cts:textxml:lang="en">SUPPLEMENT</cts:text>

                   <cts:option>case-insensitive</cts:option>

                    <cts:option>unstemmed</cts:option>

                  </cts:word-query>

                </cts:element-query>

                <cts:word-query>

                  <cts:textxml:lang="en">SUPPLEMENT</cts:text>

                 <cts:option>case-insensitive</cts:option>

                 <cts:option>unstemmed</cts:option>

                </cts:word-query>

     </cts:or-query>

    </cts:and-query>

   <cts:and-query>

     <cts:or-query>

                <cts:element-word-queryweight="16">

                  <cts:elementxmlns:_1="http://www.wolterskluver.com/namespace/meta">_1:DocTitle</cts:element>

                  <cts:textxml:lang="en">ABC</cts:text>

                  <cts:option>case-insensitive</cts:option>

                </cts:element-word-query>

                <cts:element-query>

                  <cts:elementxmlns:_1="http://www.wolterskluver.com/namespace/meta">_1:Meta</cts:element>

                  <cts:word-query weight="2">

                    <cts:textxml:lang="en">ABC</cts:text>

                    <cts:option>case-insensitive</cts:option>

                  </cts:word-query>

                </cts:element-query>

                <cts:word-query>

                  <cts:textxml:lang="en">ABC</cts:text>

                 <cts:option>case-insensitive</cts:option>

                </cts:word-query>

     </cts:or-query>

   </cts:and-query>

 </cts:and-query>

</cts:and-query>


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值