I'm uncertain about one ambiguity in your model, you are able to find
messages through FOLLOWS and IS_VISIBLE_BY. These will give two different
sets, and my first impression was that FOLLOWS gives you the right answer.
In other words you want to query for 'all messages by users I follow'? In
that case you do not need IS_VISIBLE_BY. However, if there are messages by
people you follow, but are not allowed to see, then you also need the
IS_VISIBLE_BY. But I would still reconsider linking directly from the viewer
to the message for that case. I'd rather have the messages linked to some
categorization structure for things like 'public', 'private', etc.
Anyway, here are some suggestions for the various approaches above:
*'all messages by users I follow'*
val msgs = viewer.traverse(
Order.BREADTH_FIRST, StopEvaluator.END_OF_GRAPH,
(tp: TraversalPosition) => IsMessage(tp.currentNode()),
Rels.FOLLOWS, Direction.OUTGOING,
Rels.CREATED, Direction.OUTGOING)
*'all messages visible to me'*
val msgs = viewer.traverse(
Order.BREADTH_FIRST, StopEvaluator.END_OF_GRAPH,
ReturnableEvaluator.ALL_BUT_START_NODE,
Rels.IS_VISIBLE_BY, Direction.INCOMING)
*'all messages, visible to me, by people I follow'*
val msgs = viewer.traverse(
Order.BREADTH_FIRST, StopEvaluator.END_OF_GRAPH,
(tp: TraversalPosition) => {
val msg = tp.currentNode()
IsMessage(msg) && IsVisibleBy(msg,viewer)
},
Rels.FOLLOWS, Direction.OUTGOING,
Rels.CREATED, Direction.OUTGOING)
Of course I assume you make the utility functions IsMessage(node: Node) and
IsVisibleBy(msg: Node, user: Node), and these will test the existance of
properties and relations as appropriate to make the decision.
On Wed, Mar 17, 2010 at 6:32 AM, Lincoln <[email protected]> wrote:
> Hi, I've just started looking at Neo4j and I'm quite intrigued. However,
> the cognitive dissonance that I've grown so used to in modeling storage is
> proving to be a bit difficult to let go at this early stage :)
>
> I was hoping that if someone could help me through an example I would be
> able to grok how to properly structure my data and query it in Neo4j.
>
> Nodes:
> Message( text: String )
> User( id: Long )
>
> Relationships:
> CREATED
> FOLLOWS
> IS_VISIBLE_BY
>
> So I might have a graph with entries like so:
>
> User(1) --> CREATED --> Message("i woke up late today")
> User(2) --> CREATED --> Message("hello")
> User(3) --> CREATED --> Message("ugh, i hate mondays")
>
> User(1) --> FOLLOWS --> User(2)
>
> Let's also say all messages are visible to User 1.
>
> Message("i woke up late today") --> IS_VISIBLE_BY --> User(1)
> Message("hello") --> IS_VISIBLE_BY --> User(1)
> Message("ugh, i hate mondays") --> IS_VISIBLE_BY --> User(1)
>
> So, I can do a simple traversal for visible:
>
> val graphDb = new EmbeddedGraphDatabase( "path/to/neo4j-db" )
> val index = new LuceneIndexService( graphDb )
> val viewer = index.getSingleNode("id", 1)
> val msgs = viewer.traverse( Order.BREADTH_FIRST,
> StopEvaluator.END_OF_GRAPH,
> ReturnableEvaluator.ALL_BUT_START_NODE, Rels.IS_VISIBLE_BY,
> Direction.INCOMING)
> msgs.toList.map(_.toJson).mkString("{ msgs : [", ",", "] }") // assuming i
> have the relevant functions
>
> But let's say that this is going to return too many messages. Just because
> all the messages are possibly visible to me, doesn't mean I want to see
> them
> all. So, I'd like to additionally filter by the FOLLOWS relationship. I'd
> like to express "get all messages that are visible and were created by a
> user that I follow." Can someone show me an example of how to do that?
>
> I'm guessing that you need to implement a custom ReturnableEvaluator, but I
> don't understand how you traverse multiple relationships at the same time.
>
> Thanks,
> Lincoln
> _______________________________________________
> Neo mailing list
> [email protected]
> https://lists.neo4j.org/mailman/listinfo/user
>
_______________________________________________
Neo mailing list
[email protected]
https://lists.neo4j.org/mailman/listinfo/user