根据 2 个属性的存在对顶点进行排序

Sort vertices by presence of 2 properties

更新 1

我添加了 descLengthimageLength 属性以便于排序。这个想法是 constant(0) 可以用来为缺少 属性 的用户填充值,任何大于 0 的长度都可以用来识别实际拥有 属性 的用户.这让我最远的是一次只能 order().by() 一个 属性,使用如下查询:

g.V().
  order().
    by(coalesce(values('descLength'), constant(0)))

但这不是满足我需要的完整解决方案。


原版Post

在亚马逊海王星中,我想根据 descimage 这两个属性的存在对顶点进行排序。排名顺序应该是:

考虑这张用户及其属性图:

g.addV('user').property('type','person').as('u1').
  addV('user').property('type','person').property('desc', 'second person').property('descLength', 13).as('u2').
  addV('user').property('type','person').property('desc', 'third person').property('descLength', 12).property('image', 'https://www.example.com/image-3.jpeg').property('imageLength', 36).as('u3').
  addV('user').property('type','person').property('image', 'https://www.example.com/image-4.jpeg').property('imageLength', 36).as('u4')

使用我列出的排名顺序,结果应该是:

我见过的 order().by() 示例处理数字和日期等数据,这些数据可以按 increasing/decreasing 值排序,但当然不能使用 url 和文本等字符串。实现此目标的正确方法是什么?

第一个查询并不完全是您要查找的内容,因为它将 'image' 和 'desc' 视为相同的权重,但是有了这个基础,应该可以构建出任何变体查询以更好地满足您的需求。

给定:

g.V().hasLabel('user').
      project('id','data').
        by(id).
        by(values('desc','image').fold()).
  order().
    by(select('data').count(local),desc)

我们得到

{'id': '92c04ae3-5a7f-ea4c-e74f-e7f79b44ad3a', 'data': ['third person', 'https://www.example.com/image-3.jpeg']}
{'id': 'e8c04ae3-5a7f-2cfb-cc28-cd663bd58ef9', 'data': ['second person']}
{'id': 'c8c04ae3-5a80-5707-8ba6-56554de98f33', 'data': ['https://www.example.com/image-4.jpeg']}
{'id': 'a6c04ae3-5a7e-fd0f-1197-17f3ce44595f', 'data': []}

在此基础上,我们可以更进一步,根据每种情况下存在的属性数量计算分数。下面的查询给出 descimage 更高的分数,因此在它们不存在的情况下,desc 将排序更高。

g.V().hasLabel('user').
      project('id','data','score').
        by(id).
        by(values('desc','image').fold()).
        by(union(
             has('desc').constant(2),
             has('image').constant(1),
             constant(0)).
            sum()).
  order().
    by(select('score'),desc)

产生

{'id': '92c04ae3-5a7f-ea4c-e74f-e7f79b44ad3a', 'data': ['third person', 'https://www.example.com/image-3.jpeg'], 'score': 3}
{'id': 'e8c04ae3-5a7f-2cfb-cc28-cd663bd58ef9', 'data': ['second person'], 'score': 2}
{'id': 'c8c04ae3-5a80-5707-8ba6-56554de98f33', 'data': ['https://www.example.com/image-4.jpeg'], 'score': 1}
{'id': 'a6c04ae3-5a7e-fd0f-1197-17f3ce44595f', 'data': [], 'score': 0}

更新 2022-05-06 展示如何只获取 ID

采用上面的查询,从结果中获取 ID 就像在查询末尾添加一个 select('id') 一样简单。

g.V().hasLabel('user').
      project('id','data','score').
        by(id).
        by(values('desc','image').fold()).
        by(union(
             has('desc').constant(2),
             has('image').constant(1),
             constant(0)).
            sum()).
  order().
    by(select('score'),desc).
  select('id')

但是,我们也可以删除查询为获取结果所做的一些其他工作。我主要包括那些用于演示目的。所以我们可以将查询减少到:

g.V().hasLabel('user').
      project('id','score').
        by(id).
        by(union(
             has('desc').constant(2),
             has('image').constant(1),
             constant(0)).
            sum()).
  order().
    by(select('score'),desc).
  select('id')