Uniquely indexed entities

125 views
Skip to first unread message

Mattias Persson

unread,
Jan 2, 2012, 9:03:29 AM1/2/12
to ne...@googlegroups.com
Hi all,

as the new year takes its first stumbling steps a first version of support for uniquely indexed nodes/relationships just got pushed to github. It's guaranteed to work correctly for multiple threads and in HA. It's encapsulated in:

  Index#putIfAbsent( node, key, value );

and while that is fine, it can also be a bit low-level. So to get to the (in many cases) more useful get-or-create functionality there's the (stateless) UniqueFactory:

  // An example
  UniqueFactory<Node> personFactory = new UniqueFactory.UniqueNodeFactory( graphDb, "persons" )
  {
      @Override
      protected void initialize( Node createdPerson, String key, Object value )
      {
          createdPerson.setProperty( key, value );
          // ... or any other initialization needed for a created person
      }
  };

  Node myPerson = personFactory.getOrCreate( "id", "1234567890" );

It'd be grand if one or more of you guys would try it out and give feedback about it! REST support is coming shortly.

--
Mattias Persson, [mat...@neotechnology.com]
Hacker, Neo Technology
www.neotechnology.com

Nigel Small

unread,
Jan 2, 2012, 9:10:05 AM1/2/12
to ne...@googlegroups.com
That looks incredibly useful and something I can probably use right away in the Geoff plugin :-)

Thank you!
 
Nigel Small

Tobias Lindaaker

unread,
Jan 2, 2012, 9:40:23 AM1/2/12
to ne...@googlegroups.com
While Mattias and I were implementing this, there were a few things we realized would probably come up as requests in this thread sooner or later. I'll go ahead and list them right away:

Compound uniqueness
The ability to add something to an index with multiple key/value mappings and have the combination of these mappings form a unique mapping. Example:
index.putIfAbsent( tobias, {"first name": "Tobias", "last name": "Lindaaker"} );
Where it would be possible to have many nodes with the first name "Tobias", and many nodes with the last name "Lindaaker", but only one with that combination.

We would need some object representing that group of key/value pairs in order to support such operations.
The simplest idea is to just use a java.util.Map, but that would require reconstructing the internal query-object multiple times, it would be nice if some object could be pre-constructed and reused in between invocations to get() and putIfAbsent().

Unique relationships for a given (pair of) node(s)
This isn't really an index feature, but something that comes to mind when discussing uniqueness.
What it is is a shortcoming in the REST API. There is no way in the REST API today to create a single relationship, failing if one already exists. In the embedded API this is possible today, since creating a relationship locks the nodes you create the relationship between. Even if those locking semantics should change in the future it would still be possible to explicitly lock the node(s) to ensure such semantics. That is not possible in the REST API today (unless you want to write a plugin).
The reason this is related to indexes is because many people today use indexes for some relationships in order to avoid loading all relationships for a few heavy nodes in their database.
The reason I bring this up is because I want to say that I think solving this in indexes is wrong, better would be to solve this in the REST API, around where and how relationships are created. As for the (separate) issue of loading only a subset relationships for nodes with a (very) high degree, that is being worked on and will be resolved separately on the appropriate level.

Cheers,
Tobias
--
Tobias Lindaaker <tobias.l...@neotechnology.com>
Hacker, Neo Technology
www.neotechnology.com
Cellphone: +46 706 534857 (Swe); +1 650 450 3806 (US)

James Thornton

unread,
Jan 2, 2012, 2:49:48 PM1/2/12
to ne...@googlegroups.com


On Monday, January 2, 2012 8:40:23 AM UTC-6, Tobias Ivarsson wrote:
We would need some object representing that group of key/value pairs in order to support such operations.
The simplest idea is to just use a java.util.Map, but that would require reconstructing the internal query-object multiple times, it would be nice if some object could be pre-constructed and reused in between invocations to get() and putIfAbsent().

What encoding the values in a concatenated string or byte array? 


- James



Reply all
Reply to author
Forward
0 new messages