1

我正在尝试使用search:searchAPI 在 Marklogic 中进行搜索。

let $q := "Foo ^ Bar"
let $start := 0
let $page-length := 10

search:search($q ,$config:SEARCH-OPTIONS ,$start ,$page-length)

$config:SEARCH-OPTIONS一堆搜索选项在哪里。

我的数据库中有两条记录,但上面的查询应该只返回一条。

现在,当我搜索时,我得到 1 个匹配项。但是,我得到的结果总数为 2。这是错误的,然后我将“未过滤”设置应用于查询,并且有两个匹配项。但是,为什么过滤后的查询会给我 BEFORE 过滤结果的计数,给我一个不正确的总数?

有没有办法让 Marklogic 给出实际计数?fn:count如果您返回每个结果,则有效,但如果您使用分页,这显然不起作用。

4

2 回答 2

3

不幸的是,搜索 API 不会做你想做的事。获得 100% 准确计数的唯一方法是执行fn:count过滤后的查询结果。如果您的结果有两个结果,则不会太耗时,但如果您的搜索返回数百万个文档,则令人望而却步。这就是为什么在内部,搜索 api 使用 xdmp:estimate 并且不能配置为其他方式。

解决这个问题的常用方法是使用消息传递和 UI;确保您的 UI 讨论了近似的结果计数,并且不要让分页控件一次性将用户带入结果集太远,以防它们超出最后。谷歌就是这种方法的一个很好的例子。

在规模的另一端,我已经成功地简单地检查了搜索 API 的计数估计,并将其替换为fn:count如果结果集看起来足够小以至于用户可能会注意到估计和实际计数之间的差异的输出(如您的示例。)在这种情况下,成本fn:count应该很低。

您没有明确询问,因此您可能知道这一点,但在这种情况下估计错误的原因很可能是您在查询字符串中包含标点符号,这导致无法仅从索引解析查询(我假设您的两个文档都包含单词“Foo”和“Bar”,而区别因素是其中只有一个包含“^”?)。如果您的应用程序允许排除该选项,那么它将为您提供更可靠的估计。

如果您确定您的结果集总是很小,最后的选择是完全绕过搜索 API 并cts:search直接调用。然后,您可以自由地在结果上运行自己fn:count的结果并按您喜欢的方式对它们进行分页。您可以cts:query自己以编程方式构建一个,也可以使用 search:parse 函数生成搜索 api 将在内部使用的 cts 查询,然后简单地将其传递给您cts:search自己。

于 2013-06-17T19:27:39.243 回答
2

为什么过滤后的查询会给我 BEFORE 过滤结果的计数?

因为总数基于xdmp:estimateor cts:remainder,它总是返回与索引中的查询匹配的未过滤片段计数。http://docs.marklogic.com/guide/search-dev/count_estimate上的文档讨论了这个主题:“实际上,xdmp:estimate 将通过使用索引来优化计数的决定交到开发人员手中。”

您可以使用fn:count代替xdmp:estimatects:remainder- 但是您的应用程序将使用结果总数执行 O(n)。通常最好的策略是使用xdmp:estimateor cts:remainder,但要安排文档结构和数据库索引,以便估计准确。

于 2013-06-17T19:20:09.660 回答