Marklogic wildcard search(通配符搜索)笔记
来源:互联网 发布:lol淘宝半价点券 编辑:程序博客网 时间:2024/04/28 14:59
Marklogic是企业级的NOSQL数据库。存储基于XML的以文档为中心的数据。提供了强大高效的Search API。Marklogic 6之前主要是基于XQuery的API,6之后推出了相应的Java API。目前Java API还在评估中,项目中还主要是用XQuery实现。这个产品在美国用的比较多,在国内用户寥寥无几。所以网上很少能找到相关的资料。好在其官方文档相对完备,开发中大部分的问题也都可以解决。但有些问题要颇费周折才能找出其中的原因,接下来要说的wildcard search(通配符搜索)就是这样。故用此文记录下来,作为参考。
我们有个需求,需要根据数据库中某个元素的的值支持通配符搜索,而且是以输入的关键字为头结合通配符的尾部去匹配结果。例如:
数据库中有3个xml数据,其中title元素分别为:<title>Wildcard search test</title>,<title>FW: Wildcard search test</title>,<title>RE: Wildcard search test</title>;如果用户输入“Wildcard search *”关键字来查询,只能返回第一个xml,因为第二,三个不是以"Wildcard search"开头的。我在数据库中插入了三条测试数据,然后用Search API根据需求实现如下的Search逻辑。
(:insert test xml:)xdmp:document-insert("/test/test1.xml",<test id="test1"><from>user1</from><to>user2</to><title>Wildcard search test</title><time>2014-05-10T11:07:49.000Z</time></test>)xdmp:document-insert("/test/test2.xml",<test id="test2"><from>user2</from><to>user3</to><title>FW: Wildcard search test</title><time>2014-05-11T11:07:49.000Z</time></test>)xdmp:document-insert("/test/test3.xml",<test id="test3"><from>user3</from><to>user2</to><title>RE: Wildcard search test</title><time>2014-05-12T11:07:49.000Z</time></test>)
xquery version "1.0-ml";declare namespace html = "http://www.w3.org/1999/xhtml";import module namespace search = "http://marklogic.com/appservices/search" at "/MarkLogic/appservices/search/search.xqy";(: search logic implementation :)declare function local:query ($query as xs:string) { let $final-query := cts:registered-query(cts:register( cts:query(search:parse($query, <options xmlns="http://marklogic.com/appservices/search"> <grammar> <quotation>"</quotation> <implicit> <cts:and-query strength="20" xmlns:cts="http://marklogic.com/cts"/> </implicit> <starter strength="30" apply="grouping" delimiter=")">(</starter> <starter strength="40" apply="prefix" element="cts:not-query" tokenize="word">NOT</starter> <joiner strength="10" apply="infix" element="cts:or-query" tokenize="word">OR</joiner> <joiner strength="20" apply="infix" element="cts:and-query" tokenize="word">AND</joiner> <joiner strength="10" apply="infix" element="cts:or-query">,</joiner> <joiner strength="50" apply="constraint">:</joiner> </grammar> <constraint name="Title"> <value> <element name="title" ns="" /> <term-option>case-insensitive</term-option> <term-option>punctuation-insensitive</term-option> <term-option>whitespace-insensitive</term-option> <term-option>wildcarded</term-option> </value> </constraint> <constraint name="From"><value><element ns="" name="from"/></value></constraint> <constraint name="To"><value><element ns="" name="to"/></value></constraint> <return-query>true</return-query> </options>)) ),'unfiltered', 0) return $final-query};let $key-words := 'Title:"Wildcard search *"'let $final-query := local:query($key-words)return cts:search(/test, $final-query)
用以上的实现,理论上来说就可以满足这个需求,应该只会return test1.xml的内容,但实际情况是test1.xml, test2.xml, test3.xml全都返回了。这就让人很费解。也花了很多时间research官方文档,尝试找出问题到底出在哪里。起初把大部分的注意力集中在wildcard query option的使用是不是有问题。很多次的实验和官方文档都说明,这么用是对的。开发常用的谷歌、百度也都帮不上忙,用的人不多,更没人遇到类似的问题。只能在官网上继续研究。最后把注意力放到cts:registered-query上,这个方法是用来返回注册后的query的(出于性能考虑,可以将常用固定不变的query注册到数据库里)。文档对这个方法的第二个参数的描述是,可以传入“filtered”或"unfiltered"。主要的意思是“filtered”是用来去重的。“unfiltered”可能会返回重复的数据。文档上又说“filtered” is not currently available. "unfiltered" is required in the current release. 提供了两个可选项,但第一个不能支持。不太理解他们为什么要这么设计,可能是实现上遇到了某些问题。然后尝试不注册这个query,每次都用新的,代码如下。
declare function local:query ($query as xs:string) { let $final-query := cts:query(search:parse($query, <options xmlns="http://marklogic.com/appservices/search"> <grammar> <quotation>"</quotation> <implicit> <cts:and-query strength="20" xmlns:cts="http://marklogic.com/cts"/> </implicit> <starter strength="30" apply="grouping" delimiter=")">(</starter> <starter strength="40" apply="prefix" element="cts:not-query" tokenize="word">NOT</starter> <joiner strength="10" apply="infix" element="cts:or-query" tokenize="word">OR</joiner> <joiner strength="20" apply="infix" element="cts:and-query" tokenize="word">AND</joiner> <joiner strength="10" apply="infix" element="cts:or-query">,</joiner> <joiner strength="50" apply="constraint">:</joiner> </grammar> <constraint name="Title"> <value> <element name="title" ns="" /> <term-option>case-insensitive</term-option> <term-option>punctuation-insensitive</term-option> <term-option>whitespace-insensitive</term-option> <term-option>wildcarded</term-option> </value> </constraint> <constraint name="From"><value><element ns="" name="from"/></value></constraint> <constraint name="To"><value><element ns="" name="to"/></value></constraint> <return-query>true</return-query> </options>)) return $final-query};
运行就可以得到想要的结果,只是test1.xml被返回。我们暂时只能做一个折衷的解决方案,判断传入的关键字是不是包含“Title”,如果包含就用不注册的query,如果不包含就用注册的query。同时将这个问题report给Marklogic的官方,后面的版本中也许会解决这个问题。
0 0
- Marklogic wildcard search(通配符搜索)笔记
- linux 通配符(wildcard)
- abap如何实现支持通配符*模糊查询(support wildcard search)
- Marklogic search development
- [LeetCode]Wildcard Matching 通配符匹配(贪心)
- 44. Wildcard Matching(通配符匹配)
- Marklogic search development -1.Developing Search Applications in MarkLogic Server
- struts通配符 wildcard
- Struts2.1-WildCard(通配符)
- Makefile wildcard通配符使用方法。
- Wildcard Matching 通配符匹配
- Wildcard Matching 通配符匹配
- Wildcard Matching 通配符匹配
- Wildcard Matching:通配符匹配
- 通配符(WildCard)与正则表达式(Regular Expression)
- LeetCode OJ 之 Wildcard Matching(通配符匹配)
- 动态规划 —— 求解通配符问题(wildcard)
- 正则表达式与 Linux shell 中的通配符(wildcard)
- “基于Mahout的大数据分析实践”技术讲座圆满结束
- 完成文件上传
- sencha touch自定义表单验证
- 2048游戏作者:2048的成功和我
- 正确实现AutoCAD布局打印过程详解
- Marklogic wildcard search(通配符搜索)笔记
- C++ Daily 《6》---- 类静态对象与函数静态对象
- hbase的CoprocessorProtocol及一个简单的通用扩展实现
- AchartEngine动态更新ContentProvider数据并绘图
- visual profiler 调试cuda并行程序:根据行号定位出错行
- 内置配置读者
- linux进程通信---几个发送信号的函数(kill,raise,alarm,pause)
- 调用focus方法使输入框获得焦点,不弹出软键盘的解决方法
- QNX 系统日志设计