简体   繁体   English

如何根据边类型 OrientDb 对顶点进行排序?

[英]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:这里是图表形式: VContainers & VItems VPriorityMappings

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实例,具体取决于:

  1. How many high priority items it has它有多少个高优先级项目
  2. How many medium priority items it has它有多少个中等优先级项目
  3. How many low priority items it has它有多少低优先级项目

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM