按边属性中的重合数排序结果

Order results by number of coincidences in edge properties

我正在研究推荐其他用户的推荐系统。第一个结果应该是与“搜索者”用户最“相似”的用户。用户回答问题,相同方式回答问题的数量即为相似度。

问题是我不知道怎么写查询

所以用技术术语来说,我需要根据具有特定 属性 值的边的数量对用户进行排序,我尝试了这个查询,我认为它应该有效,但它不起作用:

   let query = g.V().hasLabel('user');

   let search = __;
   for (const question of searcher.questions) {
      search = search.outE('response')
            .has('questionId', question.questionId)
            .has('answerId', question.answerId)
            .aggregate('x')
            .cap('x')     
   }

   query = query.order().by(search.unfold().count(), order.asc);

引发此 gremlin 内部错误:

org.apache.tinkerpop.gremlin.process.traversal.step.util.BulkSet cannot be cast to org.apache.tinkerpop.gremlin.structure.Vertex

我也试过每个问题有多个.by(),但结果并没有按照巧合的数量排序。

如何编写此查询?

当你 cap() 一个 aggregate() 它 returns 一个 BulkSet 这是一个 Set 计算每个对象在其中存在的次数Set。当您通过展开每个对象相关的计数大小来迭代它时,它的行为类似于 List。所以你得到你的错误,因为 cap('x') 的输出是 BulkSet 但是因为你在一个循环中构建 search 你基本上只是在那个 [=15= 上调用 outE('response') ] 这不是有效的语法,因为 has() 需要一个图 Element,例如错误指示的 Vertex

我想你更喜欢这样的东西:

let query = g.V().hasLabel('user').
              outE('response');

let search = [];
for (const question of searcher.questions) {
  search.push(has('questionId', question.questionId).
              has('answerId', question.answerId));
}

query = query.or(...search).
              groupCount().
                by(outV())
              order(local).by(values, asc)

我可能没有完全正确的 javascript 语法(我在 or() 中使用了 spread syntax 来快速传达需要发生的事情的想法)但基本上是这个想法这是过滤符合您的问题条件的边缘,然后使用 groupCount() 来计算这些边缘。

如果您需要计算未连接的用户数量,那么也许您可以切换到 project() - 可能像:

let query = g.V().hasLabel('user').
              project('user','count').
                by();

let search = [];
for (const question of searcher.questions) {
  search.push(has('questionId', question.questionId).
              has('answerId', question.answerId));
}

query = query.by(outE('response').or(...search).count()).
              order().by('count', asc);

fwiw,我认为您可能会考虑为您的数据使用不同的模式,这可能会使该推荐算法更像图形。一个想法可能是使 question/answer 成为一个顶点(可能是一个 "qa" 标签)并让边从用户顶点到 "qa" 顶点。然后用户直接link到他们给的question/answer。您可以通过边缘轻松地看到用户给出相同 question/answer 组合的直接关系。该更改使查询在提问时更自然地流动,"What users answered questions in the same way user 'A' did?"

g.V().has('person','name','A').
  out('responds').
  in('responds').
  groupCount().
  order(local).by(values)

通过这一更改,您可以看到我们可以摆脱所有这些 has() 过滤器,因为它们隐含在 "responds" 边中,这些边将它们编码到图形数据本身中。