知识库

使用 apoc.load.jsonParams 将 Zendesk 数据加载到 Neo4j,以了解文章订阅者

以下文档介绍了如何利用 Zendesk API 将 Zendesk 数据加载到 Neo4j,特别是关于选择订阅/关注知识库部分的用户数据。本文档旨在解决 Zendesk 问答中描述的问题。尽管 Zendesk UI 允许用户订阅/关注知识库部分,但它没有提供一个等效的 UI 供 Zendesk 管理员查看哪些用户订阅了每个部分。

下面的 Cypher 代码将创建支持索引,然后迭代每个部分,请求与该部分相关的所有 user_id,创建 user_id 和部分之间的关系,然后用更多识别详细信息填充 user_id。

create index on :Section(id);
create index on :User(id);
create index on :Organization(id);

// get all sections
CALL apoc.load.jsonParams("https://your_domain.zendesk.com/api/v2/help_center/sections.json",{Authorization:"Basic base64Encoded_username:password"},null)
  yield value as sectionvalue
  with sectionvalue
  unwind sectionvalue.sections as section_item
    Merge (n:Section {id:section_item.id,name:section_item.name, created_at:section_item.created_at, updated_at:section_item.updated_at,url:section_item.html_url})
    with section_item.id as secid
    // foreach section then find the subscribers
    CALL apoc.load.jsonParams("https://your_domain.zendesk.com/api/v2/help_center/sections/"+secid+"/subscriptions.json?per_page=200",{Authorization:"Basic base64Encoded_username:password"},null)
       yield value as subscribervalue
       with subscribervalue, secid
       unwind subscribervalue.subscriptions as subscription_item
            // create the relationship from the User to the Secction through the :Follows relationship
            match (s:Section {id:secid}) with s,subscription_item
            merge (n:User {id: subscription_item.user_id})
            merge (n)-[:Follows {subscribed_on: subscription_item.created_at}]->(s)
            with subscription_item.user_id as s_userid
            CALL apoc.load.jsonParams("https://your_domain.zendesk.com/api/v2/users/"+s_userid+".json",{Authorization:"Basic base64Encoded_username:password"},null)
                 yield value as userRecord
               with userRecord, s_userid
               unwind userRecord.user as uid
               match (n:User {id:s_userid})
               set
                     n.name=uid.name,
                     n.email=uid.email,
                     n.created_at=uid.created_at,
                     n.last_login=uid.last_login_at,
                     n.url=uid.url;

match (n:User) where exists(n.organization_id)
      with n,n.organization_id as organization_id
      CALL apoc.load.jsonParams("https://your_domain.zendesk.com/api/v2/organizations/"+organization_id+".json",{Authorization:"Basic base64Encoded_username:password"},null)
      yield value as orgRecord
      unwind orgRecord.organization as orgid
      with n,orgid
      merge (o:Organization {id: orgid.id, name: orgid.name, created_at: orgid.created_at})
      merge (n)-[:IS_MEMBER_OF_ORG]->(o);

加载 140 个节点(81 个用户、7 个部分、52 个组织)及其关联关系耗时 54 秒。

在上面的 Cypher 代码中,您需要替换所有出现的

`your_domain`  with the actual domain your Zendesk is hosted under
`base64Encoded_username:password` with the base64 encoding (https://www.base64encode.org/) of a Zendesk
 Admin user and password who has Admin rights in Zendesk

此外,要使用基本身份验证,您必须在 Zendesk 支持管理界面的“管理员 > 渠道 > API”中启用密码访问

最后,根据 Zendesk API,如果您预计每次 API 调用会返回超过 100 个结果,则需要考虑分页。

分页 默认情况下,大多数列表端点每页最多返回 100 条记录。您可以通过在请求 URL 参数中传递 per_page 参数来按请求更改记录数量。例如:per_page=50。但是,在大多数端点上,您每页不能超过 100 条记录。

当响应超出每页最大值时,您可以通过递增 page 参数来分页浏览记录。例如:page=3。列表结果在响应正文中包含 next_page 和 previous_page URL,以便于导航。

将上述 Cypher 代码复制到 shell 脚本文件(例如 build_zd.cql)中,然后可以通过运行 cypher-shell 来执行它,命令为:

$ cat build_zd.cql | bin/cypher-shell

因此,生成的图模型定义如下:

image

整个图显示如下:

image

从中我们将看到有 4 个部分(即绿色节点/圆圈)没有订阅者(即左上角的 4 个绿色节点)。另外三个部分有订阅者,尽管右侧的部分订阅者最多(即蓝色节点/圆圈)。此外,一些订阅者/用户选择关注多个部分。

每个节点定义有以下属性

User:
        name
        email
        created-at
        last_login
        url
        suspended
        orgainization_id
        id

Section:
            name
            url
            created_at
            updated_at
            id

Organization:
                 name
                 created_at
                 id

查询图的有用 Cypher 语句

  1. 查找按部分订阅的用户数量

    match     (n:Section)
    return     n.name,
               size (  (n)<-[:Follows]-() ) as subscribers
    order by   subscribers desc;
  2. 查找每个部分的订阅用户及其关联组织,以及用户何时订阅

    match (s:Section)<-[r:Follows]-(u:User)-[:IS_MEMBER_OF_ORG]->(o:Organization)
    return      s.name,
                u.name,
                u.email,
                o.name,
                u.suspended,
                r.subscribed_on as DateWhenSubscribed
    order by    s.name,
                o.name,
                u.name
© . All rights reserved.