2015-09-04 62 views
3

我正在通过REST API使用结构化查询来访问MarkLogic数据库(v8.0-3)。我无法弄清楚如何配置索引以“开始”查询文本字段。例如,如果一家公司被命名为“Sunday Sunshine Inc.”我希望能够通过搜索以“sund”开始(也​​包含“阳光”)来找到它。类似的查询 - 以“suns”开头 - 应该而不是找到该公司。如何使用MarkLogic查询“开始”查询cts:query()

例如下面的“开始”查询应该找不到文档,但它的作用:

xquery version "1.0-ml"; 

xdmp:document-insert("/test/doc",<a>Sunday Sunshine Inc.</a>); 
let $term := "suns" 
return cts:search(fn:collection(), 
      cts:element-value-query(xs:QName("a"),$term || "* *", 
     ("wildcarded","unstemmed","case-insensitive")),"unfiltered") 

我已经配置了以下指标:

  • 词搜索
  • 字位置
  • 快速词组搜索
  • 快速区分大小写搜索
  • 快变音敏感的搜索
  • 快速元素词搜索
  • 元素字位置
  • 快速元素短语搜索
  • 元素值位置
  • 三个字符的搜索
  • 三个字符的字位置
  • 快元素字符搜索
  • 尾随通配符搜索

另外下面的查询获得正确的结果(例如,没有命中):

xquery version "1.0-ml"; 

xdmp:document-insert("/test/doc",<a>Sunday Sunshine Inc.</a>); 
let $term := "suns" 
return cts:element-value-match(xs:QName("a"),$term || "*", 
             ("case-insensitive")) 

但使用cts:element-value-match()需要通过REST接口,我宁愿不要做一个定制约束查询。但我觉得奇怪的cts:element-value-match(),这是未经过滤的,工作 - 所以索引必须在那里评估查询。

任何帮助表示赞赏。

+0

你是否试过用'filtered'而不是'unfiltered'运行?这应该有助于我的想法。如果您不想过滤,您还可以考虑使用范围索引和元素范围查询。这将不支持通配符,但您可以在字符串上使用gt/le类型的运算符。 – grtjn

+0

感谢您的快速响应。我们真的更愿意使用未经过滤的 - 可能的响应数量可能很大(数百万),并且过滤可能需要一段时间。我们已经讨论过使用范围指数,但这是我认为的最后一招。我们可以通过在代码点上加1来得出上限范围,但我们必须考虑变音符和大小写 - 不必介意我们会添加另一个范围索引... –

+0

您应该可以解决变音符号和大小写与排序。查看在将任何字符串范围索引添加到数据库时可以在管理界面中找到的排序规则构建器。 – grtjn

回答

3

从上面的意见组成:

查询功能,如cts:element-value-query利用所谓的万能指标。该索引基本上是一个支持MarkLogic全文搜索的单词词典。要搜索值,它首先将该值标记为“单词”以查找包含所有必需“单词”的片段。

接下来,如果element word positions已启用,它可以通过检查'words'的顺序来节省筛选。显然,过滤并未完全取消,仍然需要过滤掉误报。

功能如cts:element-value-match不与cts:search或相关。此外,它们需要一个范围索引,可以在文档中阅读:http://docs.marklogic.com/cts:element-value-match

因为这些匹配函数依赖于范围索引,它只查看索引的值词典。由于该词典是为该特定元素构建的,并且范围值总是匹配从字符串的开始到结束,因此像suns*这样的模式不会返回误报。范围索引也保存在内存中以便快速访问。这就是为什么范围索引是有效的,并且不需要过滤。他们的代价是占用磁盘和内存空间,并放慢吞吐量。

注意:整理可以非常有用地忽略像情况下,变音符号和空白的东西。您可以在搜索引导指南中阅读更多关于此的信息:http://docs.marklogic.com/guide/search-dev/encodings_collations

范围查询唯一的缺点是您无法对它们执行通配符搜索。但是,很容易就可以调用其中的一个值匹配函数,使其返回所有相关值,并在其上有效地执行所谓的霰弹枪(OR)。您也可以先取数值,然后从数值匹配中调用,然后用它构造一个>= AND <种类的范围查询。

HTH!