Neo4J - 聚合数据

Neo4J - Aggregating data

我继承了一个代码库,该代码库使用递归 Neo4J v1.9.4 密码从 XML 文件中提取数据并将它们 'as is' 存储在 Neo4J 数据库中。

我需要使用 Cyphers 从这个 Neo4J 数据库中提取和聚合数据,我有一个关于特定字段内数据聚合的问题。

下面的 XML 数据结构提供了 Neo4J 数据库中存储内容的准确表示:

<description type="1">
 <narrative>
 General activity description text. Long description of the activity with no particular structure.
 </narrative>
 <narrative xml:lang="fr">
Activité générale du texte de description. Longue description de l'activité sans structure particulière.
 </narrative>
</description>
<description type="2">
 <narrative>
 Objectives for the activity, for example from a logical framework.
 </narrative>
 <narrative xml:lang="fr">
 Objectifs de l'activité, par exemple à partir d'un cadre logique.
 </narrative>
</description>
<description type="3">
 <narrative>
 Statement of groups targeted to benefit from the activity.
 </narrative>
 <narrative xml:lang="fr">
 Déclaration de groupes ciblés pour bénéficier de l'activité.
 </narrative>
</description>

我想创建一个密码,它将 return 描述标签中包含的三个英语叙述标签的内容作为一个组合值 - returned 数据应如下所示:

一般activity描述文字。没有特定结构的 activity 的详细描述。目标为activity,例如来自一个逻辑框架。受益于 activity.

的群体声明

更复杂的是,Cypher 还必须处理描述标签少于 3 个的情况。边缘案例示例(纯粹就数据结构而言,它可能相当普遍)如下:

<description>
 <narrative>
 General activity description text. Long description of the activity with no particular structure.
 </narrative>
 <narrative xml:lang="fr">
Activité générale du texte de description. Longue description de l'activité sans structure particulière.
 </narrative>
</description>

*请注意,当只有一个描述标签时,type=1 属性不是必需的。

根据这个 XML 数据结构,Cypher 的输出需要是:一般 activity 描述文本。 activity 没有特别说明

最后要注意的一点是英语叙述 XML 标签可能包含也可能不包含 xml:lang="en" 属性。

我想从描述结构中出现的任何缺少语言属性或值为 xml:lang="en".

的叙述标签中提取内容

我们目前有点卡在 Neo4J 1.9.4 版上,因此升级数据库以从产品的更高版本中获取功能并不是一个真正的选择。

密码如下:

START   n=node:entities(type="iati-activity")
MATCH   n-[:`participating-org`]-o,
        n-[:`reporting-org`]-ro,
        n-[:`title`]-ti,
        n-[:transaction]-t-[:`transaction-type`]-tt,
        n-[?:description]-d,
        t-[:value]-v,
        n-[:`activity-status`]-status,
        t-[:`provider-org`]-po,
        n-[?:`recipient-country`]-country,
        n-[?:`recipient-region`]-region
WHERE   o.role  = 1
        AND HAS(o.ref) AND o.ref IN ["GB","GB-1"]     
        AND tt.code = 1
        AND HAS(po.`provider-activity-id`)
RETURN  n.`iati-identifier`?          as funded,
        ro.`narrative`                as reporting, 
        ti.`narrative`            as title,
        COALESCE(d.`narrative`?,"")   as description,
        po.`provider-activity-id`     as funding,
        COALESCE(v.currency?, "GBP")    as currency,
        SUM(v.value)                  as funds,
        status.code?               as status,
        COALESCE(country.code?,region.code?,"")   as recipient 

这个 Cypher return 是一个数据集,其中三个描述中的每一个都分配给两个接收国,因此有六行 returned 数据。

|资助 |报告 |标题 |说明 |资金 |货币 |资金 |状态 |收件人 |

| AA-AAA-123456789-ABC123 |有机名 |标题 de la actividad | Declaration de groupes ciblés pour bénéficier de l'activité。 | GB-1-202035 |欧元 | 2000 | 2 |股份公司 |

| AA-AAA-123456789-ABC123 |有机名 |标题 de la actividad | Declaration de groupes ciblés pour bénéficier de l'activité。 | GB-1-202035 |欧元 | 2000 | 2 |自动对焦 |

| AA-AAA-123456789-ABC123 |有机名 |标题 de la actividad | Activité générale du texte de de 描述。长椅描述 de l'activité sans structure particulière。 | GB-1-202035 |欧元 | 2000 | 2 |股份公司 |

| AA-AAA-123456789-ABC123 |有机名 |标题 de la actividad | Objectifs de l'activité,par example à partir d'un cadre logique。 | GB-1-202035 |欧元 | 2000 | 2 |股份公司 |

| AA-AAA-123456789-ABC123 |有机名 |标题 de la actividad | Activité générale du texte de de 描述。长椅描述 de l'activité sans structure particulière。 | GB-1-202035 |欧元 | 2000 | 2 |自动对焦 |

| AA-AAA-123456789-ABC123 |有机名 |标题 de la actividad | Objectifs de l'activité,par example à partir d'un cadre logique。 | GB-1-202035 |欧元 | 2000 | 2 |自动对焦 |

我想要针对两行 return 接受国数据的合并描述(包含加在一起的三个描述叙述)。预先感谢您提供的任何帮助。

更新: 我已经能够创建以下 Cypher 将数据聚合成两行但是聚合描述字段包含重复值(即所有六个描述已聚合到当我只想看到三个独特的描述聚合时,聚合描述字段)。

START   n=node:entities(type="iati-activity")
MATCH   n-[:`participating-org`]-o,
        n-[:`reporting-org`]-ro,
        n-[:`title`]-ti,
        n-[:transaction]-t-[:`transaction-type`]-tt,
        n-[?:description]-d,
        t-[:value]-v,
        n-[:`activity-status`]-status,
        t-[:`provider-org`]-po,
        n-[?:`recipient-country`]-country,
        n-[?:`recipient-region`]-region
WHERE   o.role  = 1
        AND HAS(o.ref) AND o.ref IN ["GB","GB-1"]     
        AND tt.code = 1
        AND HAS(po.`provider-activity-id`)
WITH    n as n, ro as ro, ti as ti, po as po, status as status, v as v, 
        country as country, region as region, COALESCE(d.`narrative`, "") as someText           
RETURN  n.`iati-identifier`?          as funded,
        ro.`narrative`                as reporting, 
        ti.`narrative`            as title,
        REDUCE(accum = "", txt IN collect(someText) | accum + txt + " ") AS AggregatedDescription,
        po.`provider-activity-id`     as funding,
        COALESCE(v.currency?, "GBP")    as currency,
        SUM(v.value)                  as funds,
        status.code?               as status,
        COALESCE(country.code?,region.code?,"")   as recipient

输出数据

|资助 |报告 |标题 |聚合描述 |资金 |货币 |资金 |状态 |收件人 |

| AA-AAA-123456789-ABC123 |有机名 |标题 de la actividad | Declaration de groupes ciblés pour bénéficier de l'activité。 Objectifs de l'activité,par example à partir d'un cadre logique。 Activité générale du texte de de 描述。长廊说明没有任何特定结构的活动。宣布将从活动中受益的目标群体。活动的目标,例如来自逻辑框架的目标。一般描述文本活动。没有任何特定结构的活动的详细描述。 | GB-1-202035 |美元 | 6000 | 2 |股份公司 |

| AA-AAA-123456789-ABC123 |组织名称 |活动名称 |宣布将从活动中受益的目标群体。活动的目标,例如来自逻辑框架的目标。一般描述文本活动。没有任何特定结构的活动的详细描述。宣布将从活动中受益的目标群体。活动的目标,例如来自逻辑框架的目标。一般描述文本活动。没有任何特定结构的活动的详细描述。 | GB-1-202035 |美元 | 6000 | 2 |自动对焦 |

我曾尝试将 Distinct 命令与 Coalesce 命令结合使用,以便仅聚合唯一的描述行,但这没有用。

好的,那么你的第一个问题:

I would like to create a cypher that will return the contents of the three english language narrative tags, that are held within the description tags, as one combined value - the returned data should look like this:

General activity description text. Long description of the activity with no particular structure. Objectives for the activity, for example from a logical framework. Statement of groups targeted to benefit from the activity.

据我所知,这归结为如何连接多个字符串值;您有三个 "descriptions",并且您希望将它们组合成一个字符串:

START   n=node:entities(type="iati-activity")
MATCH   n-[?:description]-d
WITH    coalesce(d.narrative, "") as someText
RETURN  REDUCE(accum = "", txt IN collect(someText) | accum + txt + " ") AS joinedText;

所以我们合并文本以去除缺失值和空值,然后 REDUCE 基本上是在进行字符串连接,使用 " " 作为分隔符并返回结果。

One final point to note is that the english language narrative XML tags may or may not contain the xml:lang="en" attribute.

好的,那么对于你更广泛的问题 - 在某些情况下你可能想按语言过滤,我想这只是一个引用 d.langWHERE 子句,虽然我无法分辨您的密码如何将 XML 中的 lang 属性存储在您的 neo4j 中。

关于订购,根据您提供的内容,我无法判断您是否以任何方式在密码中存储了 XML 标签的原始订购。您当然可以对查询结果进行排序,所以如果您的 neo4j 数据中有一些序列号保留了原始 XML 排序,这是可行的,但我不能像您那样给您查询'我没有提供足够的细节。