[英]How to sort vertices according to edge types OrientDb?
I'm quite new to OrientDb and I'm trying to figure out how to sort vertices according to a more complex schema than I am accustomed to...我对 OrientDb 很陌生,我正试图弄清楚如何根据比我习惯的更复杂的模式对顶点进行排序......
In my (simplified for StackOverflow) database, I have a bunch of Containers.在我的(为 StackOverflow 简化)数据库中,我有一堆容器。 Each Container can be associated with any number of Items.
每个 Container 可以与任意数量的 Item 相关联。 There are also PriorityMappings, each of which specifies a Priority level (High, Medium, Low) per existing Item.
还有 PriorityMappings,每一个都指定每个现有项目的优先级(高、中、低)。
What I'd like to do is to retrieve a list of Containers sorted by the highest Priority of all of the associated Items according to a specified PriorityMapping.我想做的是根据指定的 PriorityMapping 检索按所有关联项目的最高优先级排序的容器列表。
My example schema is as follows:我的示例架构如下:
CREATE CLASS VItem EXTENDS V;
CREATE CLASS VContainer EXTENDS V;
CREATE CLASS VPriorityMappings EXTENDS V;
CREATE CLASS EItem EXTENDS E;
CREATE CLASS EItemPriority EXTENDS E;
CREATE CLASS EItemPriorityLow EXTENDS EItemPriority;
CREATE CLASS EItemPriorityMedium EXTENDS EItemPriority;
CREATE CLASS EItemPriorityHigh EXTENDS EItemPriority;
CREATE VERTEX VItem SET Name = "Item 1"; // @rid #34:0
CREATE VERTEX VItem SET Name = "Item 2"; // @rid #35:0
CREATE VERTEX VItem SET Name = "Item 3"; // @rid #36:0
CREATE VERTEX VItem SET Name = "Item 4"; // @rid #37:0
CREATE VERTEX VPriorityMappings SET Name = "Priority Mappings 1"; // @rid #50:0
CREATE EDGE EItemPriorityLow FROM #50:0 TO #34:0;
CREATE EDGE EItemPriorityLow FROM #50:0 TO #35:0;
CREATE EDGE EItemPriorityMedium FROM #50:0 TO #36:0;
CREATE EDGE EItemPriorityHigh FROM #50:0 TO #37:0;
CREATE VERTEX VContainer SET Name = "Container 1", Count=2; // @rid #42:0
CREATE VERTEX VContainer SET Name = "Container 2", Count=1; // @rid #43:0
CREATE VERTEX VContainer SET Name = "Container 3", Count=5; // @rid #44:0
CREATE VERTEX VContainer SET Name = "Container 4", Count=0; // @rid #45:0
CREATE VERTEX VContainer SET Name = "Container 5", Count=3; // @rid #46:0
// -- No items for Container 1
// -- Container2 > Item1(Low) & Item4(High)
CREATE EDGE EItem FROM #43:0 TO #34:0;
CREATE EDGE EItem FROM #43:0 TO #37:0;
// -- Container3 > Item1(Low) & Item3(Medium)
CREATE EDGE EItem FROM #44:0 TO #34:0;
CREATE EDGE EItem FROM #44:0 TO #36:0;
// -- Container4 > Item2(Low)
CREATE EDGE EItem FROM #45:0 TO #35:0;
// -- Container5 > Item3(Medium) & Item4(High)
CREATE EDGE EItem FROM #46:0 TO #36:0;
CREATE EDGE EItem FROM #46:0 TO #37:0;
and here it is in graph form:这里是图表形式:
So in this example, the desired outcome would be Containers 2(High), 5(High), 3(Medium), 4(Low), 1(No Items)所以在这个例子中,期望的结果是容器 2(高)、5(高)、3(中)、4(低)、1(无项目)
I could achieve this as follows using SQL but I can't wrap my head around transposing this to OrientDB.我可以使用 SQL 按如下方式实现此目的,但我无法将其转置到 OrientDB。
-- 4/ join calculated overall container priorities, use for ordering
select c.*
from container c
inner join (
-- 3/ create pivot tabe of sum of each priority level per container
select container_id,
count(case when priority = 'HIGH' then 1 end) as high,
count(case when priority = 'MEDIUM' then 1 end) as medium,
count(case when priority = 'LOW' then 1 end) as low
from (
-- 2/ apply priorities to all Container Items
select c.id as container_id, ci.item_id, item_priorities.priority
from container c
left join container_items ci
on c.id = ci.container_id
left join (
-- 1/ determine priorities for each Item according to specified priority mapping
select mi.item_id, mi.priority
from "mapping" m
inner join mapping_items mi
on mi.mapping_id = m.id
where m.id = '#50:0'
) as item_priorities
on item_priorities.item_id = ci.item_id
) as container_item_priorities
group by container_id
) as container_priorities
on container_priorities.container_id = c.id
order by container_priorities.high desc, container_priorities.medium desc, container_priorities.low desc;
Thanks in advance!提前致谢!
Would this query be useful to you?这个查询对您有用吗?
SELECT *, !highPriorityItemCount, !mediumPriorityItemCount, !lowPriorityItemCount FROM (
SELECT
*,
out("EItem").in("EItemPriorityHigh").size() as highPriorityItemCount,
out("EItem").in("EItemPriorityMedium").size() as mediumPriorityItemCount,
out("EItem").in("EItemPriorityLow").size() as lowPriorityItemCount
FROM VContainer
ORDER BY
highPriorityItemCount DESC,
mediumPriorityItemCount DESC,
lowPriorityItemCount DESC
)
It returns VContainer
instances in order depending on:它按顺序返回
VContainer
实例,具体取决于:
I don't know the background of your model, but it might be easier to let the priority levels be their own Vertices and instead use some kind of HasPriority
edge which can be linked.我不知道您的 model 的背景,但让优先级成为他们自己的顶点可能更容易,而是使用某种可以链接的
HasPriority
边缘。
Container --HasItem--> Item --HasPriority--> Priority
Or with your naming convention perhaps something more like:或者使用您的命名约定可能更像:
VContainer --EItem--> VItem --EPriority--> VPriority
It would probably also be easier to use some sortable number inside the VPriority
class which you could project in the query to sort on.在
VPriority
class 中使用一些可排序的数字可能也更容易,您可以在查询中投影以进行排序。
The query could then be something simpler like:然后查询可能更简单,例如:
SELECT *, max(out("EItem").out("EPriority").priorityLevel, null) as priority
FROM VContainer ORDER BY priority DESC
This query example would not take the number of occurrences into account though, but I'm not sure if that is of importance.这个查询示例虽然没有考虑出现的次数,但我不确定这是否重要。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.