【问题标题】:Neo4j - querying N items per groupNeo4j - 每组查询 N 个项目
【发布时间】:2015-05-01 23:42:49
【问题描述】:

以下是我的查询:

MATCH (u:User{id:1})-[r:FOLLOWS]->(p:Publisher)<-[:PUBLISHED]-(i:Item)-[:TAGGED]->(t:Tag)<-[f:FOLLOWS]-u
RETURN a, count(t) ORDER BY count(k) DESC LIMIT 100

所以User 可以关注Publisher 和Tag。查询通过计算匹配标签找到用户可能喜欢的项目。

假设在关系u-r-&gt;p 上有两个属性MIN 和MAX。这些属性指定用户希望从每个发布者那里看到多少项目。如何重写查询以允许这样做?

【问题讨论】:

    标签: graph neo4j cypher greatest-n-per-group graph-databases


    【解决方案1】:

    这是一个想法。例如,FOLLOWS 关系有一个最小值和一个最大值集。您可以使用以下查询来根据这些值限制查询返回的数据。我也没有重写整个查询以包含标签和限制。

    // find the user and the publisher and the relationship 
    // which has the min/max parameters
    match (u:User {id: 1})-[r:FOLLOWS]->(p:Publisher)
    with u, p, r
    
    // macth the items that the publisher published
    match p-[:PUBLISHED]-(i:Item)
    
    // order them just because we can
    with u, p, r, i
    order by i.name
    
    // collect the ordered items as the total list of items
    with u, p, r, collect(i.name) as items
    
    // make sure the collection is >= the minimum size of the list
    // if so then return the items in the collection up to the max length 
    // otherwise return and empty collection
    // you might want to do something else
    with u, p, r, case 
      when length(items) >= r.min then items[..r.max]
      else []
    end as items
    return u.name, p.name, r.min, r.max, items
    

    不幸的是,您已经执行了查询以获取项目,只是为了显示目的而将它们过滤掉。最好事先知道该人的偏好,这样您就可以在查询中使用限制和参数应用最大限制。这将消除不必要的数据库命中。根据发布者的不同,可能会有很多很多的项目,并且预先限制它们可能是有利的。

    这里也有一些变体可供尝试。你也可以做这样的事情......

    // slight variation where the minimum is enforced with where instead of case
    match (u:User {id: 1})-[r:FOLLOWS]->(p:Publisher)
    with u, p, r
    match p-[:PUBLISHED]-(i:Item)
    with u, p, r, i
    order by i.name
    with u, p, r, collect(i.name) as items
    where length(items) >= r.min
    return u.name, p.name, items[..r.max]
    

    甚至这个...

    // only results actually between the min and max are returned
    match (u:User {id: 1})-[r:FOLLOWS]->(p:Publisher)
    with u, p, r
    match p-[:PUBLISHED]-(i:Item)
    with u, p, r, i
    order by i.name
    with u, p, r, collect(i.name) as items
    where length(items) >= r.min
    and length(items) <= r.max
    return u.name, p.name, items[..r.max]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-11
      • 2017-10-13
      • 2020-05-29
      相关资源
      最近更新 更多