如何使用 MarkLogic cts:query() 进行 "begins with" 查询

How to do "begins with" query with a MarkLogic cts:query()

我正在通过 REST API 使用结构化查询访问 MarkLogic 数据库 (v 8.0-3)。我不知道如何配置索引来对文本字段进行 "begins with" 查询。因此,例如,如果一家公司名为 "Sunday Sunshine Inc.",我希望能够通过搜索以 "sund" 开头(也包含 "sunshine")找到它。像这样的查询 - 以 "suns" 开头 - 应该 而不是 找到公司。

例如,以下 "begins with" 查询不应找到该文档,但它确实找到了:

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() 需要通过其余界面进行自定义约束查询,我不想这样做。但我认为它很奇怪 cts:element-value-match(),它未经过滤,但有效 - 所以索引必须存在才能评估查询。

感谢任何帮助。

由以上评论组成:

cts:element-value-query 等查询函数利用了所谓的通用索引。该索引本质上是一个支持MarkLogic全文搜索的词库。要搜索值,它首先将值标记为 'words' 以查找包含所有必需 'words'.

的片段

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

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

因为这些匹配函数依赖于范围索引,它只看索引的值词典。由于该词典是为该特定元素构建的,并且范围值始终从字符串的开头到结尾匹配,因此像 suns* 这样的模式不会 return 误报。范围索引也保存在内存中以便快速访问。这就是范围索引高效且不需要过滤的原因。它们确实以占用磁盘和内存为代价 space,并且会稍微减慢摄取速度。

注意:排序规则对于忽略大小写、变音符号和白色-space 等内容非常有用。您可以在搜索开发指南中阅读更多相关信息:http://docs.marklogic.com/guide/search-dev/encodings_collations

范围查询的唯一缺点是您不能对它们进行通配符搜索。不过,很容易调用其中一个值匹配函数,使其成为 return 所有相关值,并有效地对它们执行所谓的 shotgun-OR。您还可以从值匹配调用中获取 first 和 last,并使用它来构建 >= AND < 类型的范围查询..

HTH!