我有一个数据集,其中包含许多节点,所有节点都标记为claim
,这些节点可以具有各种属性(名称P1
,P2
等,通过{{ 1}})。目前,每个P2000
节点只能包含其中一个属性,每个属性都有值,可以是不同的类型(即claim
可以是字符串,P1
可以是浮点数,P2
整数等)。我还需要能够通过任何属性(即P3
)查找节点。
我已将其建模为具有属性"find all nodes with P3 which equals to 42"
的节点,并根据P属性进行标注。然后我在标签value
和属性claim
上定义模式索引。然后查找看起来像:
value
我的第一个问题是 - 这样的索引可以吗?是否允许使用混合类型索引?
第二个问题是上面的查找有效(虽然我不确定它是否使用索引),但这并不是 - 请注意标签顺序是否已切换:
MATCH (n:P569:claim) WHERE n.value = 42 RETURN n
neo4j-sh (?)$ MATCH (n:claim:P569) WHERE n.value>0 RETURN n;
IncomparableValuesException: Don't know how to compare that. Left: "113" (String); Right: 0 (Long)
属性都是数字,但是有其他P值的字符串属性,其中一个是" 113"。不知何故,即使我说标签应该是声明和P569," 113"值仍然包含在比较中,即使它没有P569标签:
P569
这里有什么问题 - 为什么它适用于一个标签订单而不是另一个?这个数据模型可以改进吗?
答案 0 :(得分:3)
让我至少尝试一步一步解决你的问题,还有另一种方法可以解决这个问题,至少可以解决你的一些问题。
您将属性名称编码为标签。也许您希望这样做以加快查找该属性适用的节点子集;仍然看起来你因为鞋子无法比拟的数据值全部进入名为" value"的同一属性而导致很多困难。
如果除了使用这些标签之外,每个属性的名称与值相同,该怎么办?即:
CREATE (n:P569:claim { P569: 42});
您仍然可以获得标签查找,但通过隔离属性名称,您可以保证查询计划程序永远不会在构建执行计划的过程中意外地比较无法比较的值。您对此节点的查询将是:
MATCH (n:P569:claim) WHERE n.P569 > 5 AND n.P569 < 40 RETURN n;
请注意,如果您知道要使用的正确标签,那么您可以保证知道要使用的正确属性名称。通过使用不同名称的属性,如果您以P569始终为整数的方式记录数据,则无法获得您所拥有的无与伦比的情况。 (我认为因为cypher执行该查询的特殊方式而发生了这种情况)
这里可能的缺点是,如果你必须索引所有这些属性,它可能是很多索引,但仍然可能需要考虑。
答案 1 :(得分:0)
我认为退一步思考你真正想要实现的目标,以及为什么你首先拥有这些2000属性以及如何在图表中以不同方式对它们进行建模?
另外,请务必留下您不需要的属性,并使用coalesce()
提供默认属性。