You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MarkLogic Client API及数据移动API的分组聚合查询可行性咨询

回答你的MarkLogic分组聚合相关问题

当然可以实现你要的分组统计需求!下面针对你的三个疑问逐一说明:

1. 使用MarkLogic Java Client API执行分组查询与聚合

完全没问题,你有两种主要方式来实现:

方式一:利用客户端API的原生聚合功能

MarkLogic Java Client API支持通过StructuredQueryBuilder构建过滤查询,搭配AggregateBuilder定义分组聚合逻辑。针对你的三个索引字段,你可以直接指定分组键并统计每组数量:

StructuredQueryBuilder qb = new StructuredQueryBuilder();
AggregateBuilder aggBuilder = new AggregateBuilder();
// 按三个索引字段分组,统计每组的count
aggBuilder.groupBy(
  qb.element("index1"),
  qb.element("index2"),
  qb.element("index3")
).count("group-count");

QueryManager queryMgr = client.newQueryManager();
SearchHandle resultsHandle = queryMgr.search(
  qb.and(), // 这里替换成你的业务过滤条件
  new SearchHandle().withAggregate(aggBuilder)
);

// 解析聚合结果
AggregateResult aggResult = resultsHandle.getAggregateResult("group-count");
for (Group group : aggResult.getGroups()) {
  System.out.println("分组键:" + group.getKeys() + ",数量:" + group.getCount());
}

方式二:直接调用服务器端的cts函数

你提到的cts:element-value-co-occurrences完全可以在客户端API中使用,通过**原始查询(Raw Query)**功能直接执行服务器端XQuery/JS代码,灵活性拉满:

String xquery = "cts:element-value-co-occurrences( " +
  "xs:QName('index1'), xs:QName('index2'), xs:QName('index3'), " +
  "('frequency', 'item-order')" +
")";

QueryManager queryMgr = client.newQueryManager();
RawXQueryQuery query = queryMgr.newRawQueryBuilder().newRawXQueryQuery(xquery);
DOMHandle resultsHandle = new DOMHandle();
queryMgr.search(query, resultsHandle);

// 解析返回的DOM结构,提取每组的键和count值

2. 通过Data Movement API实现相同功能

Data Movement API(DMS)主打大规模数据的批量处理(比如导出、转换、批量更新),它本身没有直接的分组聚合API,但可以结合其他逻辑实现:

推荐方案:服务器端聚合+DMS导出

最高效的方式是先通过cts:element-value-co-occurrences或客户端聚合功能在服务器端完成统计,再用DMS的ExportBatcher把聚合结果导出到客户端,避免客户端处理海量原始数据。

备选方案:客户端批量聚合(小数据量适用)

如果必须在客户端做统计,可以用QueryBatcher遍历所有符合条件的文档,在BatchListener中维护统计Map:

QueryBatcher batcher = client.newDataMovementManager().newQueryBatcher(
  new StructuredQueryBuilder().and() // 你的过滤条件
).withBatchListener(new BatchListener<DocumentPage>() {
  private final Map<List<String>, Integer> groupCounts = new ConcurrentHashMap<>();

  @Override
  public void processEvent(Batch<DocumentPage> batch) {
    for (DocumentRecord record : batch.getItems()) {
      // 从文档中提取三个索引字段的值
      String val1 = record.getContent(new StringHandle().withXPath("/root/index1"));
      String val2 = record.getContent(new StringHandle().withXPath("/root/index2"));
      String val3 = record.getContent(new StringHandle().withXPath("/root/index3"));
      List<String> key = Arrays.asList(val1, val2, val3);
      groupCounts.put(key, groupCounts.getOrDefault(key, 0) + 1);
    }
  }
});

// 启动批处理并等待完成
JobTicket ticket = client.newDataMovementManager().startJob(batcher);
batcher.awaitCompletion();
client.newDataMovementManager().stopJob(ticket);

// 输出统计结果
groupCounts.forEach((key, count) -> System.out.println(key + ": " + count));

⚠️ 注意:这种方式只适合小数据量场景,大数据量下会给客户端带来极大内存压力,优先选择服务器端聚合。

3. cts:element-value-co-occurrences在MarkLogic Client API中的使用

完全可以用!你只需要通过客户端的原始查询功能,直接执行包含该函数的服务器端代码即可。除了Java客户端,Node.js客户端也支持类似逻辑:

const marklogic = require('marklogic');
const client = marklogic.createDatabaseClient({/* 你的连接配置 */});

const xquery = `cts:element-value-co-occurrences(
  xs:QName('index1'), xs:QName('index2'), xs:QName('index3'),
  ('frequency', 'item-order')
)`;

client.query(marklogic.queryBuilder.raw(xquery))
  .result()
  .then(results => {
    // 处理返回的统计结果
    console.log(results);
  });

总结一下:优先用服务器端的cts:element-value-co-occurrences或客户端原生聚合功能,性能最优;DMS适合批量处理场景,若要聚合推荐先在服务器端完成再导出。

内容的提问来源于stack exchange,提问作者brunovianarezende

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:42:42