In a typical graph with relationships Person--ordered-->Item trying to generate a *subgraph of similar Items for a given Person*.
subgraph = person.out_e('ordered') .in_v # items the person ordered .in('ordered') # other people who ordered the same items
.out_e('ordered') .in_v # other people's other ordered items .subgraph
This traversal returns a subgraph of Person--ordered-->Item<--ordered--Person-->ordered-->Item which we don't want fully. Instead, we want to exclude the Person in between by calling it 'similar' and return a subgraph of Person--ordered-->Item--similar-->Item
The point is to solve the problem 1) without a preprocessed similarity and 2) in the traversal as much as possible without extra post-processing. Any help, ideas would be appreciated.
Subgraph is created based on #paths (basically just replace subgraph with paths). You may simply want to grab the paths instead and create a subgraph of your own design based on it. Should be pretty straight forward. A subgraph is not that difficult to create. You can see the code for it at https://github.com/pangloss/pacer/blob/develop/lib/pacer/transform/pa...
I was going to suggest an alternative method of including a map step which could do additional processing that wouldn't appear in the paths and therefore in the subgraph, but actually you wouldn't be able to put an edge that doesn't exist in the source graph in that way anyhow.
On Tue, Mar 20, 2012 at 5:52 AM, Burak Arikan <ari...@gmail.com> wrote: > Hi there,
> In a typical graph with relationships Person--ordered-->Item trying to > generate a *subgraph of similar Items for a given Person*.
> subgraph = person.out_e('ordered') > .in_v # items the person ordered > .in('ordered') # other people who ordered the same > items > .out_e('ordered') > .in_v # other people's other ordered items > .subgraph
> This traversal returns a subgraph of > Person--ordered-->Item<--ordered--Person-->ordered-->Item which we don't > want fully. Instead, we want to exclude the Person in between by calling it > 'similar' and return a subgraph of Person--ordered-->Item--similar-->Item
> The point is to solve the problem 1) without a preprocessed similarity and > 2) in the traversal as much as possible without extra post-processing. Any > help, ideas would be appreciated.
On Tuesday, March 20, 2012 11:52:22 AM UTC+2, Burak Arikan wrote:
> Hi there,
> In a typical graph with relationships Person--ordered-->Item trying to > generate a *subgraph of similar Items for a given Person*.
> subgraph = person.out_e('ordered') > .in_v # items the person ordered > .in('ordered') # other people who ordered the same > items > .out_e('ordered') > .in_v # other people's other ordered items > .subgraph
> This traversal returns a subgraph of > Person--ordered-->Item<--ordered--Person-->ordered-->Item which we don't > want fully. Instead, we want to exclude the Person in between by calling it > 'similar' and return a subgraph of Person--ordered-->Item--similar-->Item
> The point is to solve the problem 1) without a preprocessed similarity and > 2) in the traversal as much as possible without extra post-processing. Any > help, ideas would be appreciated.
Best for you to first look at how subgraph is implemented and basically copy/paste that method into your code and update it. Perhaps eventually I'll support some transformation in the subgraph method but I hadn't thought of it when implementing it.
Once you've got the subgraph code, all you need to do is grab an array composed of items 0, 1, 2, 6 and run the subgraph creation stuff on it then add in the edge between 2 and 6.
> On Tuesday, March 20, 2012 11:52:22 AM UTC+2, Burak Arikan wrote:
>> Hi there,
>> In a typical graph with relationships Person--ordered-**->Item trying to >> generate a *subgraph of similar Items for a given Person*.
>> subgraph = person.out_e('ordered') >> .in_v # items the person ordered >> .in('ordered') # other people who ordered the same >> items >> .out_e('ordered') >> .in_v # other people's other ordered items >> .subgraph
>> This traversal returns a subgraph of Person--ordered-->Item<--** >> ordered--Person-->ordered-->**Item which we don't want fully. Instead, >> we want to exclude the Person in between by calling it 'similar' and return >> a subgraph of Person--ordered-->Item--**similar-->Item
>> The point is to solve the problem 1) without a preprocessed similarity >> and 2) in the traversal as much as possible without extra post-processing. >> Any help, ideas would be appreciated.
paths = person.out_e('ordered')
.in_v # items the person ordered
.in('ordered') # other people who ordered the same items
.out_e('ordered') .in_v # other people's other ordered items
.paths
On Wednesday, March 21, 2012 12:21:28 AM UTC+2, Darrick Wiebe wrote:
> Best for you to first look at how subgraph is implemented and basically > copy/paste that method into your code and update it. Perhaps eventually > I'll support some transformation in the subgraph method but I hadn't > thought of it when implementing it.
> Once you've got the subgraph code, all you need to do is grab an array > composed of items 0, 1, 2, 6 and run the subgraph creation stuff on it then > add in the edge between 2 and 6.
> Cheers,
> Darrick
> On Tue, Mar 20, 2012 at 6:05 PM, Burak Arikan wrote:
>> Thanks Darrick,
>> In the latest version of Pacer I see .subgraph returns a #<TinkerGraph> >> while .paths returns a list of paths.
>> On Tuesday, March 20, 2012 11:52:22 AM UTC+2, Burak Arikan wrote:
>>> Hi there,
>>> In a typical graph with relationships Person--ordered-**->Item trying >>> to generate a *subgraph of similar Items for a given Person*.
>>> subgraph = person.out_e('ordered')
>>> .in_v # items the person ordered
>>> .in('ordered') # other people who ordered the same >>> items
>>> .out_e('ordered') >>> .in_v # other people's other ordered items
>>> .subgraph
>>> This traversal returns a subgraph of Person--ordered-->Item<--**
>>> ordered--Person-->ordered-->**Item which we don't want fully. Instead, >>> we want to exclude the Person in between by calling it 'similar' and return >>> a subgraph of Person--ordered-->Item--**similar-->Item
>>> The point is to solve the problem 1) without a preprocessed similarity >>> and 2) in the traversal as much as possible without extra post-processing. >>> Any help, ideas would be appreciated.
Sorry, this is the actual traversal of the previous post:
subgraph = person.out_e(edge) .in_v # items the person ordered .in_e('order_from') # other people who ordered the same items .out_v .out_e('order_from') .where('weight > 9') # ...only if they ordered a lot .in_v # other people's other ordered items .paths
On Tuesday, March 20, 2012 11:52:22 AM UTC+2, Burak Arikan wrote:
> Hi there,
> In a typical graph with relationships Person--ordered-->Item trying to > generate a *subgraph of similar Items for a given Person*.
> subgraph = person.out_e('ordered') > .in_v # items the person ordered > .in('ordered') # other people who ordered the same > items > .out_e('ordered') > .in_v # other people's other ordered items > .subgraph
> This traversal returns a subgraph of > Person--ordered-->Item<--ordered--Person-->ordered-->Item which we don't > want fully. Instead, we want to exclude the Person in between by calling it > 'similar' and return a subgraph of Person--ordered-->Item--similar-->Item
> The point is to solve the problem 1) without a preprocessed similarity and > 2) in the traversal as much as possible without extra post-processing. Any > help, ideas would be appreciated.
What I would do is run the subgraph code on the filtered path first, then loop through the filtered path again and add the edge to the generated subgraph. You can't easily create a simulated edge between those two vertices before the fact.
On Thu, Mar 22, 2012 at 4:39 AM, Burak Arikan <ari...@gmail.com> wrote: > Sorry, this is the actual traversal of the previous post:
> subgraph = person.out_e(edge) > .in_v # items the person ordered > .in_e('order_from') # other people who ordered the same > items > .out_v > .out_e('order_from') > .where('weight > 9') # ...only if they ordered a lot > .in_v # other people's other ordered items > .paths
> On Tuesday, March 20, 2012 11:52:22 AM UTC+2, Burak Arikan wrote:
>> Hi there,
>> In a typical graph with relationships Person--ordered-**->Item trying to >> generate a *subgraph of similar Items for a given Person*.
>> subgraph = person.out_e('ordered') >> .in_v # items the person ordered >> .in('ordered') # other people who ordered the same >> items >> .out_e('ordered') >> .in_v # other people's other ordered items >> .subgraph
>> This traversal returns a subgraph of Person--ordered-->Item<--** >> ordered--Person-->ordered-->**Item which we don't want fully. Instead, >> we want to exclude the Person in between by calling it 'similar' and return >> a subgraph of Person--ordered-->Item--**similar-->Item
>> The point is to solve the problem 1) without a preprocessed similarity >> and 2) in the traversal as much as possible without extra post-processing. >> Any help, ideas would be appreciated.
That's a good idea, tried to implement it, got two unexpected errors:
1) Here *.subgraph* on filtered *paths* throws the error below:
paths = person.out_e(edge) .in_v # items the person ordered .in_e('order_from') # other people who ordered the same items .out_v .out_e('order_from') .where('weight > 9') # ...only if they ordered a lot .in_v # other people's ordered items .paths
undefined method `subgraph' for #<Pacer::Route:0x2f4b04ac> from (irb):29:in `evaluate' from org/jruby/RubyKernel.java:1088:in `eval' from org/jruby/RubyKernel.java:1410:in `loop' from org/jruby/RubyKernel.java:1197:in `catch' from org/jruby/RubyKernel.java:1197:in `catch'
Is it because the last vertex is isolated after filtering or something, any idea how to fix it?
2) Just tested how it'd work with the actual paths by trying to add a 'similar' edge between the vertices, but got the error below:
subgraph = paths.subgraph # works as expected paths.each do |path| subgraph.create_edge(nil, path[2], path[6], 'similar') end
NativeException: java.lang.ClassCastException: com.tinkerpop.blueprints.pgm.impls.neo4j.Neo4jVertex cannot be cast to com.tinkerpop.blueprints.pgm.impls.tg.TinkerVertex from com/tinkerpop/blueprints/pgm/impls/tg/TinkerGraph.java:220:in `addEdge' from /Users/arikan/Sites/graphcm/resque/jruby/1.9/gems/pacer-0.9.1.1-java/lib/pa cer/graph/graph_mixin.rb:106:in `create_edge' from /Users/arikan/Sites/graphcm/resque/jruby/1.9/gems/pacer-0.9.1.1-java/lib/pa cer/graph/graph_mixin.rb:341:in `creating_elements' from /Users/arikan/Sites/graphcm/resque/jruby/1.9/gems/pacer-0.9.1.1-java/lib/pa cer/graph/graph_mixin.rb:106:in `create_edge' from (irb):31:in `evaluate' from /Users/arikan/Sites/graphcm/resque/jruby/1.9/gems/pacer-0.9.1.1-java/lib/pa cer/core/route.rb:115:in `each' from (irb):30:in `evaluate' from org/jruby/RubyKernel.java:1088:in `eval' from org/jruby/RubyKernel.java:1410:in `loop' from org/jruby/RubyKernel.java:1197:in `catch' from org/jruby/RubyKernel.java:1197:in `catch'
TinkerVertex vs. Neo4jVertex ... is there a way to get around this mismatch?
On Thursday, March 22, 2012 3:15:10 PM UTC+2, Darrick Wiebe wrote:
> What I would do is run the subgraph code on the filtered path first, then > loop through the filtered path again and add the edge to the generated > subgraph. You can't easily create a simulated edge between those two > vertices before the fact.
> On Thu, Mar 22, 2012 at 4:39 AM, Burak Arikan wrote:
>> Sorry, this is the actual traversal of the previous post:
>> subgraph = person.out_e(edge) >> .in_v # items the person ordered >> .in_e('order_from') # other people who ordered the same >> items >> .out_v >> .out_e('order_from') >> .where('weight > 9') # ...only if they ordered a lot >> .in_v # other people's other ordered items >> .paths
>> On Tuesday, March 20, 2012 11:52:22 AM UTC+2, Burak Arikan wrote:
>>> Hi there,
>>> In a typical graph with relationships Person--ordered-**->Item trying >>> to generate a *subgraph of similar Items for a given Person*.
>>> subgraph = person.out_e('ordered') >>> .in_v # items the person ordered >>> .in('ordered') # other people who ordered the same >>> items >>> .out_e('ordered') >>> .in_v # other people's other ordered items >>> .subgraph
>>> This traversal returns a subgraph of Person--ordered-->Item<--** >>> ordered--Person-->ordered-->**Item which we don't want fully. Instead, >>> we want to exclude the Person in between by calling it 'similar' and return >>> a subgraph of Person--ordered-->Item--**similar-->Item
>>> The point is to solve the problem 1) without a preprocessed similarity >>> and 2) in the traversal as much as possible without extra post-processing. >>> Any help, ideas would be appreciated.
For #1, the subgraph method operates on path routes not on arrays of arrays currently. Like I originally said, you won't be able to get the out of the box subgraph method to do what you need. I recommend creating a custom method to do this, or if you'd like to refactor the subgraph method based on this issue that I just created at https://github.com/pangloss/pacer/issues/17 that would be great!
For #2, the subgraph is created in a new TinkerGraph that replicates the neo4j ids of the source vertices, so what you need to do to create the edge between subgraph elements based on elements you are querying from your original graph (or from the paths) is as follows:
On Thu, Mar 22, 2012 at 11:22 AM, Burak Arikan <ari...@gmail.com> wrote: > Thanks Darrick,
> That's a good idea, tried to implement it, got two unexpected errors:
> 1) Here *.subgraph* on filtered *paths* throws the error below:
> paths = person.out_e(edge) > .in_v # items the person ordered > .in_e('order_from') # other people who ordered the same > items > .out_v > .out_e('order_from') > .where('weight > 9') # ...only if they ordered a lot > .in_v # other people's ordered items > .paths
> undefined method `subgraph' for #<Pacer::Route:0x2f4b04ac> > from (irb):29:in `evaluate' > from org/jruby/RubyKernel.java:1088:in `eval' > from org/jruby/RubyKernel.java:1410:in `loop' > from org/jruby/RubyKernel.java:1197:in `catch' > from org/jruby/RubyKernel.java:1197:in `catch'
> Is it because the last vertex is isolated after filtering or something, > any idea how to fix it?
> 2) Just tested how it'd work with the actual paths by trying to add a > 'similar' edge between the vertices, but got the error below:
> subgraph = paths.subgraph # works as expected > paths.each do |path| > subgraph.create_edge(nil, path[2], path[6], 'similar') > end
> NativeException: java.lang.ClassCastException: > com.tinkerpop.blueprints.pgm.impls.neo4j.Neo4jVertex cannot be cast to > com.tinkerpop.blueprints.pgm.impls.tg.TinkerVertex > from com/tinkerpop/blueprints/pgm/impls/tg/TinkerGraph.java:220:in > `addEdge' > from > /Users/arikan/Sites/graphcm/resque/jruby/1.9/gems/pacer-0.9.1.1-java/lib/pa cer/graph/graph_mixin.rb:106:in > `create_edge' > from > /Users/arikan/Sites/graphcm/resque/jruby/1.9/gems/pacer-0.9.1.1-java/lib/pa cer/graph/graph_mixin.rb:341:in > `creating_elements' > from > /Users/arikan/Sites/graphcm/resque/jruby/1.9/gems/pacer-0.9.1.1-java/lib/pa cer/graph/graph_mixin.rb:106:in > `create_edge' > from (irb):31:in `evaluate' > from > /Users/arikan/Sites/graphcm/resque/jruby/1.9/gems/pacer-0.9.1.1-java/lib/pa cer/core/route.rb:115:in > `each' > from (irb):30:in `evaluate' > from org/jruby/RubyKernel.java:1088:in `eval' > from org/jruby/RubyKernel.java:1410:in `loop' > from org/jruby/RubyKernel.java:1197:in `catch' > from org/jruby/RubyKernel.java:1197:in `catch'
> TinkerVertex vs. Neo4jVertex ... is there a way to get around this > mismatch?
> Burak
> On Thursday, March 22, 2012 3:15:10 PM UTC+2, Darrick Wiebe wrote:
>> What I would do is run the subgraph code on the filtered path first, then >> loop through the filtered path again and add the edge to the generated >> subgraph. You can't easily create a simulated edge between those two >> vertices before the fact.
>> On Thu, Mar 22, 2012 at 4:39 AM, Burak Arikan wrote:
>> Sorry, this is the actual traversal of the previous post:
>>> subgraph = person.out_e(edge) >>> .in_v # items the person ordered >>> .in_e('order_from') # other people who ordered the >>> same items >>> .out_v >>> .out_e('order_from') >>> .where('weight > 9') # ...only if they ordered a lot >>> .in_v # other people's other ordered >>> items >>> .paths
>>> On Tuesday, March 20, 2012 11:52:22 AM UTC+2, Burak Arikan wrote:
>>>> Hi there,
>>>> In a typical graph with relationships Person--ordered-****->Item trying >>>> to generate a *subgraph of similar Items for a given Person*.
>>>> subgraph = person.out_e('ordered') >>>> .in_v # items the person ordered >>>> .in('ordered') # other people who ordered the same >>>> items >>>> .out_e('ordered') >>>> .in_v # other people's other ordered items >>>> .subgraph
>>>> This traversal returns a subgraph of Person--ordered-->Item<--**order** >>>> ed--Person-->ordered-->**Item which we don't want fully. Instead, we >>>> want to exclude the Person in between by calling it 'similar' and return a >>>> subgraph of Person--ordered-->Item--**sim**ilar-->Item
>>>> The point is to solve the problem 1) without a preprocessed similarity >>>> and 2) in the traversal as much as possible without extra post-processing. >>>> Any help, ideas would be appreciated.