计算neo4j图形数据库以获得组合结果
是否可以创建一个图形数据库来模拟产品功能(电话),并从该模型生成所有有效的电话组合 我创建了一个这样的数据库计算neo4j图形数据库以获得组合结果,neo4j,graph-databases,Neo4j,Graph Databases,是否可以创建一个图形数据库来模拟产品功能(电话),并从该模型生成所有有效的电话组合 我创建了一个这样的数据库 CREATE (mobilephone:Phone), (screen:Component), (camera:Component), (lowrescam:Component), (hirescam:Component), (flash:Component), (mobilephone)-[:MANDATORY]->(screen), (mobilephone)-[:OPTIO
CREATE
(mobilephone:Phone),
(screen:Component),
(camera:Component),
(lowrescam:Component),
(hirescam:Component),
(flash:Component),
(mobilephone)-[:MANDATORY]->(screen),
(mobilephone)-[:OPTIONAL]->(camera),
(camera)-[:CHOOSE1]->(lowrescam),
(camera)-[:CHOOSE1]->(hirescam),
(camera)-[:REQUIRES]->(flash)
(mobilephone)-[:MANDATORY]->(screen),
(mobilephone)-[:OPTIONAL]->(camera),
(camera)-[:CHOOSE1]->(lowrescam),
(camera)-[:CHOOSE1]->(hirescam),
(camera)-[:REQUIRES]->(flash)
我希望能够获得给定型号的手机的所有有效组合
结果应该是:
产品1:
mobilephone,screen
产品2:
mobilephone,screen,camera,lowrescam,flash
产品3:
mobilephone,screen,camera,hirescam,flash
无效产品是:
mobilephone,screen,camera,lowrescam,hirescam,flash
这是因为该型号不允许使用CHOOSE1
的两种相机类型
最终目的是检查特征模型是否可以存储/计算在图形数据库中
我是Neo4j的新手,正在研究建模行为的可能方法,否则使用标记的过渡系统建模。TL;博士
你想做的是一个坏主意,因为你不能对Neo4j说“嘿,我希望每个电话节点只有一个与摄像头节点的关系,并且总是有一个屏幕,而且……”
Neo4j中存在约束,但不能约束这样的东西
Neo4j是一个数据库,正如每个数据库应该做的那样,它用于存储和使用数据,而不是创建您想要的数据(使用约束创建手机和组件的每个组合)
这种逻辑应该在应用程序中实现,然后使用良好的数据模型存储在数据库中(我提供的模型似乎不是最好的,但很好)
始终使用标签
像您这样创建节点是无用的,因为您只是创建没有标签、没有属性的空节点。此外,标签有助于确保良好的性能
例子
编辑
要匹配您的有效手机,您可以这样做:
产品1(只有一个必填项的手机):
产品2(一部电话)
正如您所看到的,请求对每个案例都非常具体。我认为您可能需要重新考虑您的数据模型,因为我认为这不是一个好的模型
让我向您推荐一个更好的数据模型:
创造
询问
然后,您可以创建与新phones节点的有效组合:
MATCH (sc:Screen:Mandatory {name: "LCD blabla HD 1500000p")
CREATE (phone:Phone {name: "Example"})-[:USES]->(sc:Screen)
RETURN phone //and here you have your first combination, a phone with just a screen.
但正如您所看到的,您必须使用手和一堆请求创建每个组合,这有点痛苦。我知道您询问了Neo4j解决方案,但我想为您提供另一个型号。正如你所说,这听起来像是在分析阶段。因此,您可能不需要数据库 该领域模型的一种方法是作为“特征流”网络,其中顶点表示“产品关注点”,定向边表示X“具有特征”Y 从源节点和接收器节点
电话
和产品
开始
如果一个关注点X需要另一个关注点Y,则从X到Y将有一条边。这实际上使关注点Y成为“强制性的”。如果有一个选项,则从X到(比如)Y和Z将有多个传出边缘。网络流链接到产品
接收器节点的最终关注点。所有产品功能的组合成为从源到接收器的所有路径的集合
下面是Clojure中的一个示例实现
有向无环图是一个散列图,顶点作为键,顶点向量作为值:
(def g
{:phone [:mobilephone]
:mobilephone [:screen]
:screen [:camera :product]
:camera [:highrescam :lowrescam]
:highrescam [:flash]
:lowrescam [:flash]
:flash [:product]})
在yEd中可视化,我们得到:
当您在这个网络中从左到右遍历时,您正在逐个功能构建您的产品功能
我们可以使用深度优先搜索从源到汇找到所有路径:
(defn all-paths [graph source sink]
(letfn [(dfs [path visited]
(let [vertex (peek path)]
(if (= sink vertex) [path]
(->> vertex
graph
(remove visited)
(mapcat #(dfs (conj path %) (conj visited %)))))))]
(dfs [source] #{source})))
以:phone
作为源,以:product
作为接收器调用,我们得到:
(all-paths g :phone :product)
([:phone :mobilephone :screen :camera :highrescam :flash :product]
[:phone :mobilephone :screen :camera :lowrescam :flash :product]
[:phone :mobilephone :screen :product])
为手机输入引入触摸屏和键盘选项非常简单:
(def g
{:phone [:mobilephone]
:mobilephone [:touchscreen :keyboard]
:touchscreen [:camera :product]
:keyboard [:camera :product]
:camera [:highrescam :lowrescam]
:highrescam [:flash]
:lowrescam [:flash]
:flash [:product]})
同样,模型中的模型:
正如预期的那样,引入新的二进制选项会使路径数增加一倍:
(all-paths g :phone :product)
([:phone :mobilephone :touchscreen :camera :highrescam :flash :product]
[:phone :mobilephone :touchscreen :camera :lowrescam :flash :product]
[:phone :mobilephone :touchscreen :product]
[:phone :mobilephone :keyboard :camera :highrescam :flash :product]
[:phone :mobilephone :keyboard :camera :lowrescam :flash :product]
[:phone :mobilephone :keyboard :product])
如果您最终决定需要一个数据库,Neo4j将为您提供一个完整的解决方案。谢谢您的回答,但在这种情况下,我不会寻找路径。例如,您可以有一个模型,其中可以有两种相机类型(相同级别的组件),我有一个特征模型,从该模型可以生成跟踪树并遍历它以获得产品。
(defn all-paths [graph source sink]
(letfn [(dfs [path visited]
(let [vertex (peek path)]
(if (= sink vertex) [path]
(->> vertex
graph
(remove visited)
(mapcat #(dfs (conj path %) (conj visited %)))))))]
(dfs [source] #{source})))
(all-paths g :phone :product)
([:phone :mobilephone :screen :camera :highrescam :flash :product]
[:phone :mobilephone :screen :camera :lowrescam :flash :product]
[:phone :mobilephone :screen :product])
(def g
{:phone [:mobilephone]
:mobilephone [:touchscreen :keyboard]
:touchscreen [:camera :product]
:keyboard [:camera :product]
:camera [:highrescam :lowrescam]
:highrescam [:flash]
:lowrescam [:flash]
:flash [:product]})
(all-paths g :phone :product)
([:phone :mobilephone :touchscreen :camera :highrescam :flash :product]
[:phone :mobilephone :touchscreen :camera :lowrescam :flash :product]
[:phone :mobilephone :touchscreen :product]
[:phone :mobilephone :keyboard :camera :highrescam :flash :product]
[:phone :mobilephone :keyboard :camera :lowrescam :flash :product]
[:phone :mobilephone :keyboard :product])