Neo4j 中的标签是否自动编入索引?
Are labels auto-indexed in Neo4j?
图形数据库的全新内容 -- 欢迎指正。
如果我想获得标有 "User" 标签的节点列表,neo4j(或其他可能的图形数据库)是否需要搜索该标签的所有节点,或者它是否以某种方式自动索引节点标签?
没有索引,(糟糕的性能)查询每个节点以查看其标签是否匹配 "User,",如下所示:
List<Node> userNodes = new List<Node>();
for (Node node : all_nodes)
{
for (Label label : node.labels())
{
if (label.name() == "User")
{
userNodes.Add(node);
// no need to look at other labels for this node
break;
}
}
}
return userNodes;
通过索引,系统会抓取一些系统管理的 "node",其下包含所有标签名称(搜索 space 数十个而不是数百万)并抓取其子项:
List<Node> userNodes = new List<Node>();
for (Node labelNode : labels_node) // where labels_node is system-managed
{
if (labelNode.name() == "User")
{
// All children of the "User" node have the label "User"
userNodes = labelNode.children();
// No need to look at other labels
break;
}
}
return userNodes;
最终,我认为这个问题是这样的:如果我正在构建一个 "things" 的列表,我需要为其检索所有 按事物类型 ,我应该使用标签来完成这个吗?或者我应该创建自己的 "Users" 节点,它指向所有用户节点,并且只在找到我想要的节点子集后才使用标签?
好像this question也差不多,虽然比较模糊但是没有得到满意的答复
是的,标签会自动编入索引,这意味着如果您有 1000 个用户节点,其中 700 个是活跃用户,则查询活跃标签只会 return 您找到 700 个活跃用户,而不会查找其他用户。
拥有超级节点并将相关节点连接到它们是一个(几乎总是)坏主意。
此外,您应该为查询目的对数据库建模,看看这个惊人的答案:
关于在节点上使用标签或索引属性之间的区别也有一个主题,这个博客 post 解释得很好:
您还应该分析您的查询,这也意味着从一开始就导入 100 万个节点是没有意义的,尝试使用 100 个并进行一些查询。
我从 neo4j 总部的某个人那里听到了一个惊人的句子:
Be faithful to your graph and the graph will be faithful to you
找到解决问题的方法!
术语方面,文档讨论 "labels and schema indexes"。 "index" 是您附加在标签 属性 上的东西,例如索引 :Person
个节点的所有 first_name
属性。
但是对于你的问题,标签 表现得像索引 因为是的,执行引擎利用它们并像你期望的索引一样使用它们,即使文档没有'把标签说成索引。
因此,举一个具体的例子,假设我们有一个包含 100 万个节点的图,其中 5 个节点的标签为 :Person
。假设我们有以下查询:
MATCH (p:Person) RETURN p;
问题归结为,cypher要考虑多少个节点?答案是5,不是100万。
您的第二个代码片段更像是 neo4j 1.9 版的一种方法;现在我不会创建这些人为的 "index nodes",也不会遍历所有可能的标签,我只是按标签匹配并完成它。
中有专门的方法
ops = GlobalGraphOperations.at(gdb);
for (Node node : ops.getAllNodesWithLabel(DynamicLabel.label("User")) {
// do sth with node
}
它在后台使用优化的标签扫描存储。
图形数据库的全新内容 -- 欢迎指正。
如果我想获得标有 "User" 标签的节点列表,neo4j(或其他可能的图形数据库)是否需要搜索该标签的所有节点,或者它是否以某种方式自动索引节点标签?
没有索引,(糟糕的性能)查询每个节点以查看其标签是否匹配 "User,",如下所示:
List<Node> userNodes = new List<Node>();
for (Node node : all_nodes)
{
for (Label label : node.labels())
{
if (label.name() == "User")
{
userNodes.Add(node);
// no need to look at other labels for this node
break;
}
}
}
return userNodes;
通过索引,系统会抓取一些系统管理的 "node",其下包含所有标签名称(搜索 space 数十个而不是数百万)并抓取其子项:
List<Node> userNodes = new List<Node>();
for (Node labelNode : labels_node) // where labels_node is system-managed
{
if (labelNode.name() == "User")
{
// All children of the "User" node have the label "User"
userNodes = labelNode.children();
// No need to look at other labels
break;
}
}
return userNodes;
最终,我认为这个问题是这样的:如果我正在构建一个 "things" 的列表,我需要为其检索所有 按事物类型 ,我应该使用标签来完成这个吗?或者我应该创建自己的 "Users" 节点,它指向所有用户节点,并且只在找到我想要的节点子集后才使用标签?
好像this question也差不多,虽然比较模糊但是没有得到满意的答复
是的,标签会自动编入索引,这意味着如果您有 1000 个用户节点,其中 700 个是活跃用户,则查询活跃标签只会 return 您找到 700 个活跃用户,而不会查找其他用户。
拥有超级节点并将相关节点连接到它们是一个(几乎总是)坏主意。
此外,您应该为查询目的对数据库建模,看看这个惊人的答案:
关于在节点上使用标签或索引属性之间的区别也有一个主题,这个博客 post 解释得很好:
您还应该分析您的查询,这也意味着从一开始就导入 100 万个节点是没有意义的,尝试使用 100 个并进行一些查询。
我从 neo4j 总部的某个人那里听到了一个惊人的句子:
Be faithful to your graph and the graph will be faithful to you
找到解决问题的方法!
术语方面,文档讨论 "labels and schema indexes"。 "index" 是您附加在标签 属性 上的东西,例如索引 :Person
个节点的所有 first_name
属性。
但是对于你的问题,标签 表现得像索引 因为是的,执行引擎利用它们并像你期望的索引一样使用它们,即使文档没有'把标签说成索引。
因此,举一个具体的例子,假设我们有一个包含 100 万个节点的图,其中 5 个节点的标签为 :Person
。假设我们有以下查询:
MATCH (p:Person) RETURN p;
问题归结为,cypher要考虑多少个节点?答案是5,不是100万。
您的第二个代码片段更像是 neo4j 1.9 版的一种方法;现在我不会创建这些人为的 "index nodes",也不会遍历所有可能的标签,我只是按标签匹配并完成它。
ops = GlobalGraphOperations.at(gdb);
for (Node node : ops.getAllNodesWithLabel(DynamicLabel.label("User")) {
// do sth with node
}
它在后台使用优化的标签扫描存储。