Xquery “怎么做?”;以“开始”;使用MarkLogic cts:query()进行查询

Xquery “怎么做?”;以“开始”;使用MarkLogic cts:query()进行查询,xquery,marklogic,Xquery,Marklogic,我正在通过RESTAPI使用结构化查询访问MarkLogic数据库(V8.0-3)。我不知道如何配置索引来执行文本字段的“开始于”查询。因此,例如,如果一家公司被命名为“Sunday Sunshine Inc.”,我希望能够通过搜索以“sund”(也包括“Sunshine”)开头的内容来找到它。像这样的查询-以“suns”开头-不应该找到公司 例如,以下“以开头”查询不应找到文档,但确实找到了: xquery version "1.0-ml"; xdmp:document-insert("/t

我正在通过RESTAPI使用结构化查询访问MarkLogic数据库(V8.0-3)。我不知道如何配置索引来执行文本字段的“开始于”查询。因此,例如,如果一家公司被命名为“Sunday Sunshine Inc.”,我希望能够通过搜索以“sund”(也包括“Sunshine”)开头的内容来找到它。像这样的查询-以“suns”开头-不应该找到公司

例如,以下“以开头”查询不应找到文档,但确实找到了:

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版本“1.0-ml”;
xdmp:文件插入(“/test/doc”,Sunday Sunshine Inc.);
let$term:=“太阳”
返回cts:search(fn:collection(),
cts:元素值查询(xs:QName(“a”),$term | |“**”,
(“通配符”、“未分段”、“不区分大小写”)、“未筛选”)
我配置了以下索引:

  • 单词搜索
  • 单词位置
  • 快速短语搜索
  • 快速区分大小写的搜索
  • 快速变音敏感搜索
  • 快速元素词搜索
  • 元素词位置
  • 快速元素短语搜索
  • 元素值位置
  • 三字符搜索
  • 三字词位置
  • 快速元素字符搜索
  • 尾随通配符搜索
此外,以下查询会获得正确的结果(例如,没有命中):

xquery版本“1.0-ml”;
xdmp:文件插入(“/test/doc”,Sunday Sunshine Inc.);
let$term:=“太阳”
返回cts:element值匹配(xs:QName(“a”),$term | |“*”,
(“不区分大小写”))
但是使用
cts:element-value-match()
需要通过rest接口进行自定义约束查询,我不希望这样做。但我觉得奇怪的是,未过滤的cts:element-value-match()可以工作,因此索引必须存在以评估查询


感谢您的帮助。

由以上评论组成:

cts:element-value-Query这样的查询函数利用了所谓的通用索引。该索引本质上是一个单词词典,支持MarkLogic中的全文搜索。要搜索值,它首先将值标记为“words”,以查找包含所有必需“words”的片段

接下来,如果启用了
元素单词位置
,它可以通过检查“单词”的顺序来保存过滤。显然,过滤并没有完全取消,仍然需要过滤掉误报

cts:element-value-match
这样的函数不能与
cts:search
或相关函数一起使用。此外,它们需要一个范围索引,如文档中所示:

因为这些匹配函数依赖于范围索引,所以它只查看索引的值词典。由于该词典是为该特定元素构建的,并且范围值总是从字符串的开头到结尾匹配,所以像
suns*
这样的模式不会返回误报。范围索引也保存在内存中,以便快速访问。这就是为什么范围索引是有效的,并且不需要过滤。它们确实是以占用磁盘和内存空间为代价的,并稍微降低了摄入速度

注意:排序规则对于忽略大小写、变音符号和空格等内容非常有用。您可以在《搜索开发指南》中阅读更多关于此的内容:


范围查询的唯一缺点是不能对其进行通配符搜索。不过,调用其中的一个值匹配函数,使其返回所有相关值,并有效地对它们执行所谓的shotgun或其他操作,是很容易的。您还可以从值匹配调用中选择第一个和最后一个,并使用该调用构造
>=并尝试使用
筛选的
而不是
未筛选的
运行吗?我想这应该会有帮助。如果你喜欢未过滤,你也可以考虑使用一个范围索引和一个元素范围查询。这将不支持通配符,但您也可以对字符串使用gt/le类型的运算符..感谢您的快速响应。我们真的更愿意使用未过滤-可能的响应数量可能很大(数百万),过滤可能需要一段时间。我们已经讨论过使用范围指数,但我认为这是最后的手段。我们可以通过向代码点添加1来推导上限范围,但我们必须考虑到变音符号和大小写-更不用说我们还要添加另一个范围索引…您应该能够使用排序规则处理变音符号和大小写。向数据库添加任何字符串范围索引时,请查看可在管理UI中找到的排序规则生成器。@grtjn再次感谢您的快速响应。我们已经考虑使用element-range-query()-因此,如果用户键入
suná
,我们可以将变音符号展平并搜索
GE suna和LT sunb
-也就是说,希望展平时不会有太多的gotchas等待。尽管如此,我还是希望有一种方法可以做到这一点,即“只起作用”——cts:element-value-match()如何做到这一点?value-match使用范围索引,所以看起来您已经有了范围索引。
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"))