0

我有一个包含数百万个文档并且跨越数年的大型数据集。

在 MarkLogic(在查询控制台中首选)中,我想使用 JavaScript 检索所有唯一的计数,memberIDs以及从 2020 年到2021 年更改为secondaryIDs的文档中的计数。status'w''y'

示例文档结构(collection = 'members'):

  {
    memberIDs: '123abc',
    secondaryIDs: 'abc123',
    year: 2021,
    field1: 'x', 
    status: 'y'
  },
  {
    memberIDs: '123abc',
    secondaryIDs: 'abc123',
    year: 2020,
    field1: 'x', 
    status: 'w'
  }

对于这个例子,答案是“2”。

我在“ MarkLogic中的索引”下的文档中找到了一种可能的解决方案,称为“shotgun 查询”。

我在Search Documents from two collections in MarkLogic也发现了一个类似的问题。但是,我不了解 XQuery,所以我不知道如何使其适应我的情况。

我的第一个想法是分别执行这两个查询,填充两个数组并确定两个数组中出现的 ID。但是,由于较大的查询会产生超过 200k 的文档,因此计算仍然需要很长时间。

我可以通过使用子序列来克服这个障碍。每次检索少量 URI,然后遍历 URI,从文档中检索我需要的值,并将它们添加到数组中。可悲的是,我的方法并没有真正奏效。此外,我正在创建的副产品本身可能就是一个问题。20 万个文档意味着我必须存储 400k 个字符串的数组。到目前为止我有这个,它没有中断,但我在 15 秒后停止运行。

let ids = []
while (startIdx < numFiles) {
  
  let uris = fn.subsequence(
    cts.uris("", null, 
      cts.andQuery([
        cts.collectionQuery('members'),
        cts.jsonPropertyValueQuery('year', 2021),
        cts.jsonPropertyValueQuery('status', 'y')
    ]),
  ), startIdx, 50).toArray();
  
  uris.forEach(uri => {
    let docObj = uri ? cts.doc(uri).toObject() : undefined;
    let memberId = docObj ? docObj.memberId : undefined;
    let secondaryId = docObj ? docObj.secondaryId : undefined;

    if (!ids.includes(memberId)) { ids.push(memberId) }
    else if (!ids.includes(secondaryId)) { ids.push(secondaryId) } 
  })

  startIdx += 50;           
}

在 SQL 中,我可能会在两个查询结果之间进行 INNER JOIN 来解决这个问题。我可以在 MarkLogic 中使用 JavaScript API 做到这一点吗?

谢谢。

4

0 回答 0