如何使用MarkLogic Optic API获取文档总数及查询后结果的统计或估算方法
MarkLogic Optic API 计数与分页结果结合方案
嘿,我来帮你搞定这两个Optic API的计数问题,刚好对应你提到的场景!
1. 如何通过MarkLogic Optic API获取文档总数量
如果只是想获取某个视图下的所有文档总数,直接用Optic的count()聚合函数就能拿到精确计数:
// 获取视图x.y的总文档数 const totalCountResult = op.fromView('x', 'y') .count('total_documents') // 指定计数结果的字段名 .result(); // 提取最终计数数值 const total = (await totalCountResult)[0].total_documents; console.log(`总文档数:${total}`);
要是你不需要绝对精确的计数,追求更快的查询性能,也可以结合cts.estimate()做估算(和你原来用的逻辑一致),在Optic里通过xpath()函数就能调用它:
const estimatedCountResult = op.fromView('x', 'y') .select(op.xpath('cts:estimate(.)', 'estimated_count')) .result(); const estimatedTotal = (await estimatedCountResult)[0].estimated_count;
2. 同时返回分页结果与过滤后的总计数
针对你提到的场景——先通过where过滤数据,再同时返回200条分页结果和过滤后的总计数,这里有两种高效的实现方式:
方式一:用fork()复用基础查询(推荐)
Optic的fork()方法可以让你在同一个带过滤条件的基础查询上分支处理,只执行一次过滤逻辑,同时拿到计数和分页结果,性能更优:
// 先定义带过滤条件的基础查询 const filteredQuery = op.fromView('x', 'y') .where(/* 这里写你的过滤条件,比如 op.eq(op.col('status'), 'active') */); // 用fork分支处理计数和分页 const [countData, paginatedData] = await filteredQuery .fork( // 分支1:统计过滤后的总数量 q => q.count('total'), // 分支2:获取前200条结果 q => q.limit(200) ) .result(); // 组装成你需要的响应结构 const response = { items: paginatedData.toArray(), count: countData[0].total };
方式二:分开执行计数和分页查询
如果你觉得fork()的写法不够直观,也可以分开执行两个查询,逻辑更清晰:
const filteredQuery = op.fromView('x', 'y') .where(/* 你的过滤条件 */); // 先获取过滤后的总计数 const countResult = await filteredQuery.count('total').result(); const totalCount = countResult[0].total; // 再获取分页数据 const items = await filteredQuery.limit(200).result().toArray(); // 组装响应 const response = { items, count: totalCount };
两种方式都能实现你想要的{ items: [...], count: N }结构,其中fork()方式因为复用了过滤后的查询上下文,在过滤条件复杂时性能表现会更好。
内容的提问来源于stack exchange,提问作者Michal Sobanski
相关产品推荐
相关产品推荐

