Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >MarkLogic中用于多个集合中文档的复杂Xquery

MarkLogic中用于多个集合中文档的复杂Xquery
EN

Stack Overflow用户
提问于 2019-09-10 04:47:33
回答 3查看 237关注 0票数 1

我们在MarkLogic中拥有庞大的数据集,文档分布在多个集合中。我们需要通过搜索分布在这些集合中的文档来开发报告。

样本数据集:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    Collection1 - Inventory [Contains 5 million Inventory documents]

    URI: /inventory/inv1
        <xml>
            <INVENTORY>
                <ItemName>10</ItemName>
                <InventoryQuantity>100</InventoryQuantity>
                .
                .
            </INVENTORY>
        </xml>


    Collection2 - Item[Contains 1 million Item documents]

    URI: /item/item1
        <xml>
            <Item>
                <ItemName>10</ItemName>
                <ItemWmos>
                    <UnitPrice>895</UnitPrice>
                    .
                    .
                <ItemWmos>
                .
                .
            </Item>
        </xml>


          For each Inventory in the Inventory collection
            Step 1 : Get "ItemName", its "InventoryQuantity" and for the same "ItemName" find "UnitPrice" from Item document in Item collection.
            Step 2 : CurrentInventoryValue = InventoryQuantity * UnitPrice
            Step 3 : TotalInventoryValue = TotalInventoryValue + CurrentInventoryValue;
         Repeat;

使用下面的XQuery,我已经达到了上述报告要求。然而,执行和显示超时异常需要大量时间。我无法在这里利用路径范围索引,因为我必须将"ItemName“和它的"InventoryQuantity”放在一起,并在具有相同项目名称的不同集合文档中搜索单价。

XQuery:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    sum(for $doc in cts:search(doc(), cts:and-query((cts:collection-query("Inventory"))))
        [(fn:string-length(//INVENTORY/ItemName/text()) > 0) and (fn:string-length(//INVENTORY/InventoryQuantity/text()) > 0)]
        let $itemName := $doc//INVENTORY/ItemName/text()
        let $inventoryQuantity := $doc//INVENTORY/InventoryQuantity/text()
    return (
        for $doc in cts:search(doc(), cts:and-query((cts:collection-query("Item"))))[//Item/ItemName/text()=$itemName 
        and (fn:string-length(//ItemWmos/UnitPrice/text()) > 0)]
        return ($inventoryQuantity * $doc//ItemWmos/UnitPrice/text())
    ))

如何有效地在MarkLogic中实现这样复杂的查询需求?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2019-09-10 07:20:20

波段援助方法:

通过将XPath表达式重写为绝对表达式并将它们转换为cts查询逻辑,您可能可以获得更好的性能。但是,即使它解决了眼前的问题,它也不会扩大到更远的范围(因为您可以迭代的文档数量没有限制):

(注意:我还没有测试过这段代码,所以可能存在语法错误)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
sum(for $doc in cts:search(doc(), cts:and-query((cts:collection-query("Inventory"))), "unfiltered")
        let $itemName := $doc/xml/INVENTORY/ItemName/string()
        let $inventoryQuantity := $doc/xml/INVENTORY/InventoryQuantity/string()
    where
      fn:string-length($itemName) gt 0 and fn:string-length($inventoryQuantity) gt 0
    return (
        for $doc in cts:search(doc(), cts:and-query((cts:collection-query("Item")), cts:elementValueQuery("ItemName", $itemName)), "unfiltered")
        return (xs:integer($inventoryQuantity) * xs:integer($doc/xml/Item/ItemWmos/UnitPrice/string()))
    ))

可扩展方法#1:

我要做的第一件事是将您在MarkLogic中拥有的/inventory/ data转换为以下格式,并将其还原为所摄取的数据:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<envelope>
  <headers xmlns="http://yoursite.com/item/headers"> <!-- Note the unique namespace -->
     <ItemName>10</ItemName>
     <InventoryQuantity>100</InventoryQuantity>
     <UnitPrice>85</UnitPrice>
     <ItemPrice>8500</ItemPrice>
  </headers>
  <attachments>
    <INVENTORY>
      <ItemName>10</ItemName>
      <InventoryQuantity>100</InventoryQuantity>
      .
      .
    </INVENTORY>
    <Item>
      <ItemName>10</ItemName>
      <ItemWmos>
        <UnitPrice>895</UnitPrice>
        .
        .
      </ItemWmos>
      .
      .
    </Item>
 </attachments>
</envelope>

现在,要运行报告,只需在<ItemPrice>上放置一个<ItemPrice>并运行cts:总和-合计

如果您使用DataHub框架,您可以更简单地管理用于提取不相交数据并协调它的过程。

可扩展方法#2:

您可以保持数据的原样,但也可以将TDE视图放在其之上,这将对数据进行索引,并允许您使用Optic来运行性能连接和从中聚合。这有一些背景开销,这使得方法1在苹果与苹果之间的比较中表现得更好,但是快速运行更广泛的各种查询的灵活性,而不必改变吞食,可能会使它对您来说是值得的。

票数 2
EN

Stack Overflow用户

发布于 2019-10-14 21:49:30

请在URI上使用xdmp:目录进行迭代。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let $var1:=<xml>
    <INVENTORY>
        <ItemName>10</ItemName>
        <InventoryQuantity>100</InventoryQuantity>
    </INVENTORY>
    <INVENTORY>
        <ItemName>10</ItemName>
        <InventoryQuantity>101</InventoryQuantity>
    </INVENTORY>
    <INVENTORY>
        <ItemName>12</ItemName>
        <InventoryQuantity>102</InventoryQuantity>
    </INVENTORY>
</xml>


let $var2:=
<xml>
    <Item>
        <ItemName>10</ItemName>
        <ItemWmos>
            <UnitPrice>895</UnitPrice>
        </ItemWmos>
    </Item>
    <Item>
        <ItemName>11</ItemName>
        <ItemWmos>
            <UnitPrice>896</UnitPrice>
        </ItemWmos>
    </Item>
    <Item>
        <ItemName>12</ItemName>
        <ItemWmos>
            <UnitPrice>897</UnitPrice>
        </ItemWmos>
    </Item>
</xml>

let $mergeInvertory:= <merge>{for $in in $var2//Item/ItemName[. eq $var1//INVENTORY/ItemName]

    return <mergeFile>{$in/..,$var1//ItemName[. eq $in]/following-sibling::InventoryQuantity}</mergeFile>
    }</merge>

let $CurrentInventoryValue:=<mergeInventory>{for $item in $mergeInvertory/mergeFile
    return <INVENTORY><ItemName>{$item//ItemName}</ItemName><UnitPrice>{data($item//UnitPrice)}</UnitPrice><InventoryQuantity>{$item//InventoryQuantity}</InventoryQuantity><TotalInventoryQuantity>{$item//UnitPrice * sum($item//InventoryQuantity)}</TotalInventoryQuantity></INVENTORY>
    }</mergeInventory>
return $CurrentInventoryValue
票数 1
EN

Stack Overflow用户

发布于 2019-09-10 10:50:12

ItemName在库存中只出现一次吗?每个ItemName值是否只出现在一个库存中?如果是这样的话,您可以使用包含cts:*-co-occurrences函数的范围索引来获取两个“表”,然后将它们相乘。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
let $itemQuantities := cts:element-value-co-occurrences(
  xs:QName('ItemName'),
  xs:QName('InventoryQuantity'),
  'map',
  cts:collection-query('Inventory')
)

let $itemPrices := cts:element-value-co-occurrences(
  xs:QName('ItemName'),
  xs:QName('UnitPrice'),
  'map',
  cts:collection-query('Item')
)

return fn:sum(
  for $itemName in map:keys($itemQuantities)
  return map:get($itemQuantities, $itemName) * map:get($itemPrices, $itemName)
)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57871156

复制
相关文章
Java集合框架中底层文档的List与Set
List为列表,中在列表中的对象是由顺序的排序的,并且是有重复的对象。 简单为:有序,有重复。
达达前端
2022/04/29
1.1K0
Java集合框架中底层文档的List与Set
SpringCloud中多个子模块如何集成Swagger文档
不知道大家工作中有没有使用Swagger,可能没有用过,但是肯定或多或少的接触过、听说过,它是一款基于Restfull接口的文档在线生成 + 功能测试的工具。
一个程序员的成长
2020/11/25
5K1
SpringCloud中多个子模块如何集成Swagger文档
java中的集合
ArrayList和LinkedList的异同? 答:二者都线程不安全,相对线程安全的Vector,执行效率高。此外,ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。对于随机访问get和set,ArrayList优于LinkedList,因为LinkedList要移动指针。对于新增和删除操作add(特指插入)和remove,LinkedList比较占优势,因为ArrayList要移动数据。
全栈程序员站长
2022/07/18
1.6K0
java中的集合
Java中的集合
Java提供了一套实现了Collection接口的标准集合类。其中一些是具体类,这些类可以直接拿来使用,而另外一些是抽象类,提供了接口的部分实现。
shimeath
2022/05/05
1.5K0
Java中的集合
Python中的集合
Python中的集合专门用于存储信息,存储的元素无序且不能重复,它用一对花括号{}定义,数据之间用逗号隔开。
阿黎逸阳
2020/09/08
1K0
python中的集合
可变集合(set):可添加和删除元素,非可哈希的,不能用作字典的键,也不能做其他集合的元素
py3study
2020/01/10
9030
Python中的集合
集合(Set)是简单对象的无序集合(Collection)。当集合中的项目存在与否比起次序或其出 现次数更加重要时,我们就会使用集合。 通过使用集合,你可以测试某些对象的资格或情况,检查它们是否是其它集合的子集,找到 两个集合的交集,等等。
benym
2022/07/14
5650
Java中的集合
开发中会使用大量相同数据类型的情况。如果使用数组来解决问题 1. 数组能够使用的方法非常少,功能方法需要程序员自己完成。 2. 数据类型单一化,不支持多种情况。 3. 数组容量不可以更改。
用户7073689
2020/03/18
1.4K0
MyBatis中的复杂映射
上一章中实现的MyBatis对象映射较为简单,对象中的属性和数据库中的表字段是一一对应的(无论数量和名称都完全一样),如果对象中的属性名和表中的字段名不一致怎么办?又或者Java对象中存在复杂类型属性(即类似Hibernate中多对一、一对多关系对象时)怎么完成数据库表和对象的映射?本章来解决这样的问题。
用户10175992
2022/11/15
2.1K0
MyBatis中的复杂映射
【Python】集合 set ② ( 集合常用操作 | 集合中添加元素 | 集合中移除元素 | 集合中随机取出元素 )
集合添加元素代码示例 : 原集合中有两个 Tom 字符串 , 只保留后面的 Tom 字符串 ; 添加元素时 , 添加 Trump 元素 , 原集合中没有该元素 , 添加成功 ; 有添加 Tom 元素 , 此时原集合中存在该元素 , 本次添加 Tom 元素失败 ;
韩曙亮
2023/10/11
2620
【Python】集合 set ② ( 集合常用操作 | 集合中添加元素 | 集合中移除元素 | 集合中随机取出元素 )
java使用xquery_如何使用Java XQuery
二、 在Eclipse中新建一个Java Project项目,将步骤一中的lib中的jar 文件导进来。
全栈程序员站长
2022/11/16
1K0
MongoDB使用update和save方法来更新集合中的文档
MongoDB 使用 update() 和 save() 方法来更新集合中的文档。接下来让我们详细来看下两个函数的应用及其区别。
用户4988376
2021/08/12
3.6K0
第49节:Java集合框架中底层文档的List与Set
List为列表,中在列表中的对象是由顺序的排序的,并且是有重复的对象。 简单为:有序,有重复。
达达前端
2019/07/03
1.2K0
第49节:Java集合框架中底层文档的List与Set
Java中的Collection集合
JAVASE提供了满足各种需求的API,在使用这些API前,先了解其继承与接口操作架构,才能了解何时采用哪个类,以及类之间如何彼此合作,从而达到灵活应用。 集合按照其存储结构可以分为两大类,分别是单列集合java.util.Collection和双列集合java.util.Map本文主要讲Collection集合,后续再补充Map集合。
共饮一杯无
2022/11/24
7030
Java中的Collection集合
Python中的集合介绍
可能看上面的文字有点抽象,什么这个集合那个集合的,接下来我们直接上案例,相信大家看了之后一目了然:
小博测试成长之路
2023/09/01
1770
Python中的集合介绍
java中的Set集合
概述 Set集合类似于一个罐子,程序可以依次把多个对象“丢进”Set集合,而Set集合通常不能记住元素的添加顺序。实际上Set就是Collection只是行为略有不同(Set不允许包含重复元素)。 Set集合不允许包含相同的元素,如果试图把两个相同元素加入同一个Set集合中,则添加操作失败,add()方法返回false,且新元素不会被加入。
全栈程序员站长
2022/08/11
1.3K0
java中的Set集合
Scala中的集合类型
----------目录--------------------------------------------------------- 1.Scala简介和安装 2.Scala语法介绍 3.Scala的函数 4.Scala中的集合类型 ------------------------------------------------------------------------------------------------------------- Scala中的集合类型     Scala提供了一套
云飞扬
2018/05/11
4.2K0
JAVA中的集合小结
Collection是最基本的集合接口,声明了适用于JAVA(List和Set)集合的通用方法
帅的一麻皮
2020/02/21
1.6K1
WCF中的集合类型
在.net中,各种类型的集合均实现了IEnumerable或者IEnumerable<T>接口,一个数据契约的数据成员可以是一个集合类型,服务契约也可以定义直接与集合交互的操作,但是这都是.net所特有的,WCf不能在元数据中公开它们,然后WCF专门为集合提供了编组原则。      在定义服务时候,无论使用的是IEnumerable<T>、IList<T>和ICollection<T>,他们的传输形式都使用了数组,如 namespace ContractInterface {     [ServiceCo
小白哥哥
2018/03/07
8840
NumPy 中的集合运算
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/119568.html原文链接:https://javaforall.cn
全栈程序员站长
2022/07/09
7220

相似问题

MarkLogic XQUERY -如何按集合和日期搜索文档?

22

MarkLogic:从XQuery文档中获取值?

22

在xquery marklogic中搜索由公共字段连接的多个集合

16

如何使用XQuery用Marklogic中的集合记录insert

12

在Marklogic Xquery中删除少于30天的文档

13
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文