Hi David and Michael,

Firstly, I knew that field argument had to be there for a reason, I
just couldn't figure it out from the examples.  ;-)  I think your
explanation is exactly what I was looking for, Michael.  I'll give it
a shot tomorrow.

And David, you are correct, I'm looking to create two queries, one to
retrieve all B's related to A and another to retrieve all C's related
to A.  I somewhat obfuscated my use case for the sake of simplicity,
but I'm actually investigating the use of a graph database to more
flexibly drive conflict resolution in a rule engine, Drools in my
case.  In this model, each rule would have a representation as a node
on the graph, and the conditions would relate to specific fact nodes
or patterns.  So lets say we have something like this:

Rule[name: 'red car costs one hundred dollars', price: 100] --
REQUIRES --> CarColor[name: red]
Rule[name: 'sedan costs five hundred dollars', price: 500] -- REQUIRES
--> CarTrim[name: sedan]

These nodes have a parity in our rule engine so that when we evaluate
a red car, its price gets set to 100; and when we evaluate a sedan its
price gets set to 500.  However, if I try to evaluate a red sedan, the
price is ambiguous.  Typically, rule engines provide a notion of
"salience," which would allow me to assign numeric priority to each
rule.  Whichever rule has the highest priority wins, and the loser
gets evicted from the "agenda."  The problem with this is that
eventually you end up writing QBASIC-like rules where one rule has a
salience of 10 and another has a salience of 20.  That way, if we have
a rule that sits in between them, we can give it a salience of 25.
This only goes so far, though, soI'm looking to do something a bit
better.  By specifying a graph hierarchy, I expect to be able to use
node traversals to do things:

1. "Discover" conflicts by detecting any other rule nodes that do not
have a "requires" constraint pointing to a node of the same type.  For
example, a rule for a red car and a rule for a green car are not in
conflict; but if i define a rule for a red car and a rule for a sedan
that doesn't also require some non-red color, I need to specify which
rule takes priority should I hit an intersection of conditions.
2. Define mechanisms for rules to "override" or "extend" other rules.
For example, if I wanted the sedan rule to take priority, I'd specify:

Rule[name: 'sedan...'] -- OVERRIDES --> Rule[name: 'red car...']

Then, in the rules engine, I'd plug in a conflict resolution strategy
take takes in an agenda of rules to fire and uses the graph to evict
the rules that were overridden by other rules on the agenda.

In the case of extension, I could have something like:

Rule[name: 'red car...', price: 100] -- EXTENDS --> Rule[name: 'red
sedan', price: 600] -- REQUIRES --> CarTrim[name: 'sedan']

This effectively defines a sub-rule for the intersection of a red car
and a sedan, but the constraints would need to be collected through a
node traversal, continue+excluding extends relationships and
include+pruning from the requires relationships (CarTrim and
CarColors).  In order to accurately compile a rule from this model,
though, I'd need to get a list of trims and color requirements
separately (as they are distinct attributes of a Car fact).

This is where the aforementioned A, B, C scenario comes into play.  Of
course, I could define separate relationship types for each attribute,
e.g. REQUIRES_TRIM, REQUIRES_COLOR, but that just seemed like a lot of
extra work.  The nature of the relationship is the same, and ideally
I'd like to derive the meaning from the Java type of the end node.  It
also allows us to add other types of constraint relationships in the
future (like CANNOT_HAVE, etc).

I'm just playing around with Neo4j for now, but so far I'm really
liking what I've seen.  On a separate, completely unrelated project,
we were able to adapt "fishhook" style parent/child hierarchies from
SQL to a graph and its opened up a whole new world of use cases for
our dev team to explore.  We're now able to navigate through
company/organization hierarchies with way less code and much better
response times.

Keep up the good work!

On Wed, Feb 23, 2011 at 7:42 PM, David Montag [via Neo4J User List]
<[email protected]> wrote:
> Cedric,
>
> Thank you for your feedback! We value it highly.
>
> I'm trying to understand your use case. You have entities of classes A, B,
> and C. Your graph looks like this:
>
> A --RELATED_TO--> B
> A --RELATED_TO--> C
>
> And you want to provide query methods for getting all B's and C's for a
> given A. Correct?
>
> If yes, could you please elaborate a bit more on the actual use case? I.e.
> what are the A's and B's and C's. It would be interesting to know what kind
> of a use case would drive this graph and these queries.
>
> Thanks,
> David
>
> On Wed, Feb 23, 2011 at 2:10 PM, cedric.hurst <[hidden email]> wrote:
>
>>
>> Firstly, thanks for your great work on the Spring Data Graph API so far.
>>  I
>> took a look at the draft you had out here:
>>
>> https://gist.github.com/835408
>>
>> And it looks like an awesome start.  I'm relatively new to Neo4J (saw the
>> SpringOne keynote and the roo talk), but one thing I think would be very
>> useful is if there was some sort of higher-level PathMapper that worked at
>> the GraphBacked level, instead of working at the Neo4j node level.
>>
>> In my immediate case, I have three NodeBacked types in my graph: TypeA,
>> TypeB, and TypeC.  Types B and C can be related to Type A through the same
>> relationship type, but I want to define two traversals that include only
>> each type respectively.  I'm using the FieldTraversalDescriptionBuilder
>> but
>> its falling down when I try to do something like the following:
>>
>> class TypeA {
>>    @GraphTraversal(traversalBuilder = RelatedTraversalBuilder.class,
>> elementClass = TypeB.class)
>>    private Iterable<TypeB> typeBs;
>>
>>    @GraphTraversal(traversalBuilder = RelatedTraversalBuilder.class,
>> elementClass = TypeC.class)
>>    private Iterable<TypeC> typeCs;
>>
>>    private static class RelatedTraversalBuilder implements
>> FieldTraversalDescriptionBuilder {
>>       public TraversalDescription build(NodeBacked start, Field field) {
>>                return new
>> TraversalDescriptionImpl().relationships(RelTypes.RELATED_TO);
>>       }
>>    }
>> }
>>
>> In this particular case, the traversal will return a mix of TypeB and
>> TypeC
>> and throw a class cast exception.
>>
>> I'd love to have some abstraction of a Path such that path.startNode() and
>> path.endNode() would return the actual NodeBacked classes themselves, so I
>> could write my PathMappers to use something like:
>>
>> class MyPathMapper implements PathMapper {
>>  public Void mapPath(GraphPath path) {
>>   if(path.endNode() instanceof TypeB) {
>>      return Evaluator.INCLUDE_AND_PRUNE
>>   } else {
>>      return Evaluator.EXCLUDE_AND_PRUNE
>>   }
>>  }
>> }
>>
>> It seems like the template should be able to provide this with something
>> along the lines of:
>>
>> interface PathMapper<T> {
>>   ...
>>    @Override
>>       public Void mapPath(GraphPath graphPath) {
>>           eachPath(graphPath);
>>           return null;
>>       }
>> }
>>
>> interface GraphPath {
>>   NodeBacked startNode();
>>   NodeBacked endNode();
>>   ...
>> }
>>
>> The key here is, of course, that GraphPath provides NodeBacked classes
>> instead of primitive neo4j nodes.  Beyond the simple instanceof example I
>> gave, I think it would also be useful for evaluating paths using on
>> NodeEntity properties rather than having to call
>> node.getProperty('somePropertyNameThatIWillProbablyMisspell').
>>
>> Not sure if my request makes sense, or is reasonable to implement, but I
>> think it would certainly make my life a lot easier.
>> --
>> View this message in context:
>>
>> http://neo4j-user-list.438527.n3.nabble.com/Neo4j-Spring-Neo4jTemplate-tp2525460p2563548.html
>> Sent from the Neo4J User List mailing list archive at Nabble.com.
>> _______________________________________________
>> Neo4j mailing list
>> [hidden email]
>> https://lists.neo4j.org/mailman/listinfo/user
>>
>
>
> --
> David Montag
> Neo Technology, www.neotechnology.com
> Cell: 650.556.4411
> [hidden email]
> _______________________________________________
> Neo4j mailing list
> [hidden email]
> https://lists.neo4j.org/mailman/listinfo/user
>
>
> ________________________________
> If you reply to this email, your message will be added to the discussion
> below:
> http://neo4j-user-list.438527.n3.nabble.com/Neo4j-Spring-Neo4jTemplate-tp2525460p2564675.html
> To unsubscribe from [Neo4j] Spring Neo4jTemplate, click here.

-- 
View this message in context: 
http://neo4j-user-list.438527.n3.nabble.com/Neo4j-Spring-Neo4jTemplate-tp2525460p2565608.html
Sent from the Neo4J User List mailing list archive at Nabble.com.
_______________________________________________
Neo4j mailing list
[email protected]
https://lists.neo4j.org/mailman/listinfo/user

Reply via email to