【问题标题】:Neo4j gem - Plucking multiple nodes/relationshipsNeo4j gem - 采摘多个节点/关系
【发布时间】:2014-12-08 00:03:03
【问题描述】:

这可能是不可能的,但我有一个这样的查询

events = Event.as(:e).where("(( e.date_start - {current_time} )/{one_day_p}) < 1 ").users(:u, :rel).where("rel.reminded = {reminded_p}" ).params(reminded_p: false, one_day_p: one_day, current_time: time).pluck(:e,:u, :rel)

目标是获取events,其中 start_date 距离不到一天。假设我试图提取事件、用户和关系。我需要对每个执行不同的操作。

我需要为每个event 获取所有users 并为每个用户执行电子邮件操作。在该操作中,电子邮件需要有权访问该event

接下来,我需要将rel.reminded 属性更新为true

有没有办法同时采摘所有这些以便能够组织和执行这些任务?我开始单独执行此操作,但我必须进行额外的查询才能实现。例如

events = Event.as(:e).where("(( e.date_start - {current_time} )/{one_day_p}) < 1 ").users(:u, :rel).where("rel.reminded = {reminded_p}" ).params(reminded_p: false, one_day_p: one_day, current_time: time).pluck(:e)

那么我必须

events.each do |event|
# do stuff
end

# do another query that is associated and do more stuff

更新:

结合答案,我有类似的东西,但还没有清理时间方法。我在其中添加了用户搜索,因为稍后我需要在电子邮件功能中考虑到这一点。所以我不确定将它包含在查询中是否比在每个用户之外执行更有效。

@collection = Event.as(:e).where("(( e.date_start - {current_time} )/{one_day_p}) < 1 ").users(:u).where(setting_reminder: true).rel_where(reminded: false ).params(one_day_p: one_day, current_time: time).pluck(:e, 'COLLECT(u)', 'COLLECT(rel)')

但是rel 没有用这个查询定义。

【问题讨论】:

    标签: ruby-on-rails neo4j neo4j.rb pluck


    【解决方案1】:

    我还想补充几点。您应该能够使用 ActiveSupport 使部分查询更容易,如下所示:

    Event.as(:e).where("date_start < {date_threshold}").params(1.day.from_now)
    

    此外,为了减少混乱,我认为将.where("rel.reminded = false") 放入(或按照克里斯建议使用rel_where(reminded: false))没有任何问题。这不是从用户传入的数据,并且在您调用查询时不会在不同时间发生变化,因此它应该同样有效。

    您可能还想使用 gem 的 v4 中的新查询链接来定义 unreminded_users 方法,如下所示:

    class Event
      def self.unreminded_users
        all.rel_where(reminded: false)
      end
    end
    

    我实际上并没有尝试在查询链中执行类似rel_where 的操作,但我怀疑它会起作用。然后你就会有这个:

    Event.as(:e).where("e.start_date < {date_threshold}").params(date_threshold: 1.day.from_now)
      .users(:u, :rel).rel_where(reminded: false)
      .pluck(:e,:u, :rel)
    

    【讨论】:

    • 要说清楚,我还是非常支持Chris提到的collect的方式,我们希望实现Eager loading,这样你就可以在不久的将来通过对象方法调用来做到这一点
    • 我终于有时间回到这个任务了。我并没有真正了解您添加的新查询链接方法适用于何处,但我会尝试查看文档以了解更多信息
    • 它很新(我认为它进入了 3.0.x 的最新补丁版本,但它可能应该等到次要或主要版本)。基本上它只是让您在各种查询中重用查询链的一部分。查看这篇关于 ActiveRecord 的博客文章,非常相似:blog.plataformatec.com.br/2013/02/…
    • 与 q 稍微相切,但我相信这两种方法都不能检测阈值。就我而言,它也会检测过去的事件。如果用户更改他们的设置以在将来接收更新,它将触发那些过去的事件。我认为在您的回答中,e.start_date 始终是 &lt; date_threshold,直到 start_date 超过 1.day.from_now,因为那是在未来。
    【解决方案2】:

    首先,如果您使用的是 gem 的 v4,请使用 rel_where 而不是 where 和字符串来表示您的关系!

    您应该能够将您的 pluck 更改为 pluck(:e, 'COLLECT(u)', 'COLLECT(rel)'),它会为您提供大量事件、用户和 rel,所有这些都基于事件分组在父数组中。它会这样组织:

      [
        [event1, [user1a, user1b, user1c], [rel1a, rel1b, rel1c]],
        [event2, [user2a, user2b, user2c], [rel2a, rel2b, rel2c]]
      ]
    

    每个rel的位置与其用户匹配,所以rel1a是事件和user1a的关系。

    您可以将其设置为@collection = my_big_query,然后在您的视图中执行@collection.each do |event, users, rels| 循环。您将对用户执行each_with_index,并且用户的索引将对应于rels 中的位置。它看起来像:

    <%= @collection.each do |event, users, rels| %>
      <%= event.name %>
      <% users.each_with_index do |user, i| %>
        <%= user.name %> said they were attending at <%= rels[i].confirmed_at %>.<br />
      <% end %>
    <% end %>
    

    【讨论】:

    • 终于回到了这个。使用像 @collection = Event.as(:e).where("(( e.date_start - {current_time} )/{one_day_p}) &lt; 1 ").users(:u).rel_where(reminded: false ).params(one_day_p: one_day, current_time: time).pluck(:e, 'COLLECT(u)', 'COLLECT(rel)') 这样的收集方法,它不知道收集中的 rel 是什么。它说rel not defined。我添加了一个编辑,我想将其更改为
    • 您可能应该使用)/{one_day_p}) &lt; {one} 并将one: 1 添加到您的参数中。 :-/
    • 发布了一个后续问题以避免过长
    猜你喜欢
    • 2014-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-06-19
    • 1970-01-01
    • 1970-01-01
    • 2014-05-24
    • 1970-01-01
    相关资源
    最近更新 更多