如何用DMSDK QueryBatch检查MarkLogic中URI列表是否存在?
批量检查MarkLogic文档URI存在性(无需拉取完整文档)
Hi Helen, 针对你在Windows 10上使用MarkLogic 9.0-8,想要通过Java代码批量验证指定URI对应的XML/二进制文档是否存在,且不想拉取完整文档的需求,我给你几个高效、轻量的实现方案:
方案一:使用DMSDK UriBatcher + MultiDocumentManager.exists
这个方案利用MarkLogic的DMSDK批量处理URI,结合MultiDocumentManager的exists方法——该方法仅检查文档是否存在,不会加载完整内容,非常适合你的场景。
代码示例
import com.marklogic.client.DatabaseClient; import com.marklogic.client.DatabaseClientFactory; import com.marklogic.client.batch.Batch; import com.marklogic.client.batch.BatchListener; import com.marklogic.client.batch.UriBatcher; import com.marklogic.client.document.MultiDocumentManager; import java.util.Arrays; import java.util.List; import java.util.Map; public class UriExistenceChecker { public static void main(String[] args) { // 初始化客户端(替换为你的服务器地址、端口、账号) DatabaseClient client = DatabaseClientFactory.newClient( "localhost", 8000, new DatabaseClientFactory.DigestAuthContext("admin", "admin") ); // 准备要检查的URI列表 List<String> urisToCheck = Arrays.asList( "/docs/report.xml", "/binaries/image.png", "/docs/missing-doc.xml" ); // 创建UriBatcher处理批量URI UriBatcher uriBatcher = client.newUriBatcher(); uriBatcher.addUris(urisToCheck.toArray(new String[0])); // 设置自定义批次监听器,处理每个URI批次的存在性检查 uriBatcher.setBatchListener(new BatchListener<String[]>() { @Override public void processBatch(Batch<String[]> batch) { String[] batchUris = batch.getItems(); MultiDocumentManager multiDocManager = client.newMultiDocumentManager(); // 批量检查,返回URI到存在状态的映射 Map<String, Boolean> existenceMap = multiDocManager.exists(batchUris); // 处理结果(这里只是打印,你可以根据需求存入集合或数据库) for (Map.Entry<String, Boolean> entry : existenceMap.entrySet()) { System.out.printf("URI [%s] 存在状态: %b%n", entry.getKey(), entry.getValue()); } } @Override public void processFailure(Batch<String[]> batch, Throwable throwable) { // 处理批次失败的情况 System.err.println("处理批次失败,URI列表: " + Arrays.toString(batch.getItems())); throwable.printStackTrace(); } }); // 启动批次处理并等待完成 uriBatcher.start(); try { uriBatcher.awaitCompletion(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); e.printStackTrace(); } finally { // 释放客户端资源 client.release(); } } }
方案优势
- 原生支持批量处理,效率远高于逐个检查URI
exists方法仅发送轻量级请求,不会拉取文档内容,节省带宽和服务器资源- 自动处理批次失败的异常场景
方案二:直接执行XQuery批量验证
如果觉得DMSDK的配置稍显繁琐,也可以直接通过Java客户端执行XQuery,利用MarkLogic内置的fn:doc-available()函数——这个函数专门用于检查文档是否存在,不会加载文档内容。
代码示例
import com.marklogic.client.DatabaseClient; import com.marklogic.client.DatabaseClientFactory; import com.marklogic.client.eval.ServerEvaluationCall; import java.util.Arrays; import java.util.List; public class XQueryUriChecker { public static void main(String[] args) { DatabaseClient client = DatabaseClientFactory.newClient( "localhost", 8000, new DatabaseClientFactory.DigestAuthContext("admin", "admin") ); List<String> urisToCheck = Arrays.asList( "/docs/report.xml", "/binaries/image.png", "/docs/missing-doc.xml" ); // 构造批量检查的XQuery String xquery = "declare variable $uris as xs:string* external;\n" + "for $uri in $uris\n" + "return fn:doc-available($uri)"; // 执行XQuery并获取结果 ServerEvaluationCall evalCall = client.newServerEval(); evalCall.addVariable("uris", urisToCheck); Boolean[] existenceResults = evalCall.evalAs(Boolean[].class); // 映射URI和结果 for (int i = 0; i < urisToCheck.size(); i++) { System.out.printf("URI [%s] 存在状态: %b%n", urisToCheck.get(i), existenceResults[i]); } client.release(); } }
方案优势
- 代码更简洁,无需配置批次处理器
- 一次请求即可处理所有URI,性能优异
fn:doc-available()对XML和二进制文档都适用,无需区分文档类型
注意事项
- 权限配置:确保你的Java客户端账号拥有目标文档的
read权限,否则会返回false(即使文档存在) - 批次大小:如果你的URI数量极大(比如上万条),建议拆分批次处理(比如每次处理500-1000个URI),避免单次请求过大导致性能问题
- 二进制文档支持:两个方案都完美支持二进制文档的存在性检查,无需额外处理
内容的提问来源于stack exchange,提问作者Helen
相关产品推荐
相关产品推荐

