2013-04-21 45 views
3

我一直在研究Tinkerpop堆栈很长一段时间。我想我对它可以做什么以及它可以很好地工作的数据库有个很好的想法。我现在正在考虑一些不同的数据库,但还没有确定。所以我决定将我的代码纯粹写入接口,并且现在不考虑的任何实现。在我看到的数据库中,它们实现TransactionalGraphKeyIndexableGraph。我认为这足够满足我需要的,但我只有一个问题。Tinkerpop Blueprints顶点查询

我有不同的'类'的顶点。使用蓝图,我认为最好通过在包含类名的每个顶点中包含一个字段来表示。这样做,我可以做类似graph.getVertices("classname", "User")的东西,它会给我所有的用户顶点。由于getVertices函数指定一个实现应该使用索引,我保证会得到一个快速查找(如果我索引该字段)。

但让我们说,我想基于两个属性检索顶点。顶点必须有className=Usersusername=admin。寻找单个顶点的最佳方法是什么?是否有可能索引这两个属性,即使并非所有的顶点都有username字段?我想要的数据库是OrientDB,Neo4j和Titan,但我还没确定。我目前也计划使用Gremlin,如果有帮助的话。

回答

3
  1. graph.getVertices()会遍历所有顶点,寻找那些与财产,如果你没有自动指数在图形中实现开启。如果你已经有了数据,并不能只是打开自动索引,你应该用的是index = indexableGraph.getIndex()然后index.get('classname', 'User')

  2. 很可能在多个对象进行query,但没有细节,就很难说了。对于Neo4j他们使用Lucene,这意味着query()将采用lucene查询,如className:Users AND username:admin,但我不能为其他人说话。

呀这些DB的是良好的摆弄,我个人认为neo4j是最容易,只要你了解他们的许可结构,你不应该使用它们有任何问题。

+0

那么,正如你所说,查询有些实现特定(不幸)。我希望能够随时切换数据库,所以我只写了我自己的查询包装器。谢谢你的帮助。 – GJK 2013-04-22 02:08:39

+0

是的,这很不幸,但这是大多数这些系统构建的方式,有些可能没有执行特定类型的查询的能力,因此他们将其留在了实现特定的位置。 – Nicholas 2013-04-22 02:12:09

+0

说'graph.getVertices()'做线性扫描是不正确的。如果图形实现KeyIndexableGraph(以及所有提到的三个图),并且指定的密钥是作为密钥索引创建的密钥,则使用索引并避免线性扫描。 https://github.com/tinkerpop/blueprints/wiki/Graph-Indices#keyindexablegraph-and-fast-lookup-of-elements-by-keyvalue-pairs – 2013-04-22 11:02:08

4

对顶点使用“类”或“类型”是划分它们的好方法。这样做的:

graph.createKeyIndex("classname",Vertex.class); 
graph.getVertices("classname", "User"); 

是一个很常见的模式,一般应该产生一个快速查找,但迭代数千万用户的一个索引可能不会那么大(如果你打算种植特定classname到非常大的尺寸)。我认为这导致了您的问题的第二部分,关于做两个财产查询。

以表面上的例子,这两个元素的查找会是这样的(使用小鬼):

g.V('classname',"User").has('username','admin') 

所以,你缩小顶点只是“用户”的顶点与键索引,然后过滤那些为“管理员”。但是,我会以不同的方式进行建模。这将是更便宜的只需做:

graph.createKeyIndex("username",Vertex.class); 
graph.getVertices("username", "admin"); 

或小鬼:

g.V('username','admin') 

如果你知道你想要的用户名,还有来模拟这个没有更好/更快的方法。如果你想遍历所有的“用户”顶点,你真的只需要classname。如果你只是想找到一个(或一组与username顶点),那么对该属性的关键索引是更好的方法。

即使我没有在其上创建密钥索引,我仍然在所有顶点上包含typeclassname属性。我发现它有助于全球运营,我可能会或可能不关心速度,但只需要一个答案。

+0

问题在于,我无法保证User类将是唯一具有用户名字段的顶点类。我们的数据模型是灵活的,可以由用户间接编辑。不能保证不同类的顶点不会共享属性名称。 – GJK 2013-04-22 19:04:03

+1

完全没有问题。该索引不需要唯一标识特定用户(虽然它可以很好)。使用索引让你关闭,然后过滤类。考虑以下区别:'gV('classname','user')。has('username','admin')''和'gV('username','admin')。has('classname','user' )'。第一个必须让所有的用户(可能有数千个或更多),然后循环他们来找到“管理员”。第二种情况要好得多,因为即使图表中存在多次“用户名”,它可能也不会返回数千次,因此您只需扫描一小撮即可找到“用户”类。 – 2013-04-23 13:50:01

+1

或者,确保架构中的唯一性。如果你不介意你的属性名称的冗长,没有理由不能用类型名称来加前缀。所以也许你觉得你需要在“用户”类和“博客”类中存储用户名(表示是谁写了一篇文章)。只需调用“用户”类顶点属性“用户名”,并调用“博客”类属性“blogUsername”。这样你确保你的索引总是返回一个类的一件事。 – 2013-04-23 13:54:18