使用DHF协调非规范化实体

时间:2019-01-08 16:08:36

标签: marklogic marklogic-dhf

我们正在使用MarkLogic 9.0.5和DHF 3.0,并且正在尝试将多个源文档协调为非规范化形式。但是,我们无法正确获取xml表单。

让我们说我们有一个家庭的原始文档,每个家庭成员一个。现在,我们要生成一个类似以下内容的统一实体:

<envelope>
<header></header>
<instance>
   <family>
     <name>Paulsen</name>
     <family-member>
         <name>John</name>
         <age>54</age>
     </family-member>
     <family-member>
         <name>Clarice</name>
         <age>38</age>
     </family-member>
   </family>
</instance>
</envelope>

但是,新的DHF结构迫使我们使用json对象映射来生成代码,但是以任何方式将数据放入对象中,我们都不会像上面那样得到它。例如:

declare function plugin:extract-instance-family
$source as node()?,
$options as map:map
) as map:map

let $name := get-family-name()
let $family-member := (<family-member>
                         <name>get-name()</name>
                         <age>get-age()</age>
                       </family-member>,
                       <family-member>
                         <name>get-name()</name>
                         <age>get-age()</age>
                       </family-member>)

let $model := 
  json:object()
    =>map:with('name', $name)
        =>map:with('family-member', '$family-member')

    return $model
};

产生一些xml,例如:

<envelope>
<header></header>
<instance>
   <family>
     <name>Paulsen</name>
     <family-member>
         <family-member>
             <name>John</name>
             <age>54</age>
         </family-member>
     </family-member>
     <family-member>
        <family-member>
           <name>Clarice</name>
           <age>38</age>
         </family-member>
     </family-member>
</instance>
</envelope>

这包含每个家庭节点两次。有关如何解决此问题的任何建议?

PS我也尝试过将嵌套的json-objects作为参数传递,但显然会导致dhf-flows中的错误:

let $family-member := json-object()
                      => map:with('family-member', 'stuff')

1 个答案:

答案 0 :(得分:1)

此行为背后有一个原因。这遵循MarkLogic实体服务中使用的模式。您可以在这里http://docs.marklogic.com/guide/entity-services/intro#id_23284进一步了解使用实体建模的好处。

与第一层为顶级实体描述属性名称不同,这可能有助于调整代码,以免元素名称冲突并且使第二层清楚地描述实体类型。 / p>

例如,

declare function plugin:extract-instance-family-type
  $source as node()?,
  $options as map:map
) as map:map

let $name := get-family-name()
let $family-member := (<family-member-type>
                         <name>get-name()</name>
                         <age>get-age()</age>
                       </family-member>,
                       <family-member>
                         <name>get-name()</name>
                         <age>get-age()</age>
                       </family-member-type>)

let $model := 
  json:object()
    =>map:with('name', $name)
        =>map:with('family-member', '$family-member')

    return $model
};

在这种情况下,您可以考虑将数据提取到Java程序的情况。顶级家庭类型实体将映射到Family Java类和该类的family-member元素的familyMember字段,最后,family-member-type将映射到FamilyMember类及其关联的字段。

此外,如果您打算将数据以JSON的形式使用,我将走得更远,建议采用使实体类型TitleCase和属性camelCase成为惯例的约定。 (FamilyType,familyMember,FamilyMemberType)。