[Neo] Popularity sorting

Johan Svensson johan at neotechnology.com
Wed Feb 10 15:14:59 CET 2010


Since we are throwing out possible solutions on how to do this I want
to mention the "graph-matching" component. The component needs an API
brushup and some documentation on how to use it (currently
non-existing...) but I think it should solve your problem nicely.

Here is a code example:

    // build "pattern" that is to be matched in the real graph
    PatternNode productX = new PatternNode();
    PatternNode productY = new PatternNode();
    PatternNode customer = new PatternNode();
    productX.addPropertyEqualConstraint( "name", "productX" );
    customer.createRelationshipTo( productX, PURCHASED );
    customer.createRelationshipTo( productY, PURCHASED );

    // get the real product X node
    Node productNode = ... // get productX node somehow, e.g. from index

    // start match on product X node
    Iterable<PatternMatch> matches =
        PatternMatcher.getMatcher().match( productX, productNode );

    // for each sub-graph that matches, use that result to calculate popularity
    // of other products (Y)
    for ( PatternMatch match : matches )
        Node customerNode = match.getNodeFor( customer );
        Node otherProductNode = match.getNodeFor( productY );

        // do the popularity calculation using otherProductNode...

So first create the pattern that should be matched, then decide where
to start the match in the real graph and finally extract all the
results and do the calculation.

Adding more constraints just means modifying the pattern to match. For
example if we are only interested in calculating the popularity of
other products for customers that are members of a specific customer
group just add:

    PatternNode customerGroup = new PatternNode();
    customerGroup.addPropertyEqualConstraint( "name", "rich_people" );
    customer.createRelationshipTo( customerGroup );

Or, maybe Bill Gates is one of our rich customers and we only want
productY's that he has bought:

    PatternNode bill = new PatternNode();
    bill.addPropertyEqualConstraint( "name", "Bill Gates" );
    bill.createRelationshipTo( productY, PURCHASED );

We could now change where to start the match (both productX and bill
will only map to a single node) and depending on how the graph looks
it may be more efficient to perform the match from the node
representing Bill Gates:

    // start match from Bill Gates
    Node billGatesNode = ... // get him somehow
    Iterable<PatternMatch> matches =
        PatternMatcher.getMatcher().match( bill, billGatesNode );

Hopefully this is enough to get started with the graph-matching
component. I personally think it has a lot of potential!


On Wed, Feb 10, 2010 at 1:32 PM, Peter Neubauer
<peter.neubauer at neotechnology.com> wrote:
> ...
> On Wed, Feb 10, 2010 at 1:27 PM, Craig Taverner <craig at amanzi.com> wrote:
>> ...
>> On Wed, Feb 10, 2010 at 1:10 PM, <rick.bullotta at burningskysoftware.com>wrote:
>>> ...
>>>   -------- Original Message --------
>>>   Subject: [Neo] Popularity sorting
>>>   From: Chris Owen <cowen at thoughtworks.com>
>>>   Date: Wed, February 10, 2010 3:05 am
>>>   To: user at lists.neo4j.org
>>>   Hi,
>>>   One of the questions that we were asked to try and answer was:
>>>   *"based on Product X find other Products Customers bought who also
>>>   bought
>>>   Product X". *
>>>   This is quite simple to traverse, but what we were now trying to answer
>>>   a
>>>   very similar question of:
>>>   *"based on Product X find other Products Customers have bought who also
>>>   bought Product X and order by Popularity". *
>>>   We have not managed to find a way without altering the internal
>>>   traverses of
>>>   Neo4J to be able to see how many times a node is found as by default it
>>>   ignores duplicates. Any ideas of how we solve this problem?
>>>   Cheers, Chris.

More information about the User mailing list