从 neo4j C# 客户端调用 algo.similarity.jaccard 算法不起作用

Calling algo.similarity.jaccard algorithm from neo4j C# client doesn't work

我有以下查询,当我在 Neoj4 浏览器上执行时它运行良好:

MATCH (p1:Book{friendlyUrl:"a-modern-witch"})-[r:BOOK_ADDED_TO_CATALOG]->(catalog1:Catalog)
WITH p1, collect(id(catalog1)) AS p1Catalog
MATCH (p2:Book)-[:BOOK_ADDED_TO_CATALOG]->(catalog2:Catalog)
WHERE p1 <> p2
WITH p1, p1Catalog, p2, collect(id(catalog2)) AS p2Catalog
RETURN p1.title AS from,
p2.title AS to,
algo.similarity.jaccard(p1Catalog, p2Catalog) AS similarity

ORDER BY similarity DESC

我想将其转换为 C# 代码,我是这样做的:

var result = _graphClient.Cypher
        .Match ("(p1:Book{friendlyUrl:'a-modern-witch'})-[r:BOOK_ADDED_TO_CATALOG]->(catalog1:Catalog)")
        .With ("p1, collect(id(catalog1)) AS p1Catalog")
        .Match ("(p2:Book)-[:BOOK_ADDED_TO_CATALOG]->(catalog2:Catalog)")
        .Where ("p1 <> p2")
        .With ("p1, p1Catalog, p2, collect(id(catalog2)) AS p2Catalog")
        .Call ("algo.similarity.jaccard(p1Catalog, p2Catalog)")
        .Yield ("value AS similiarity")
        .Return ((p1, p2, similiarity) => new {
          bk1 = p1.As<BookDetailsDto> (),
          bk2 = p2.As<BookDetailsDto> (),
        })
        .Limit (10);

不幸的是,当我通过 API 调用它时,出现以下错误:

An unhandled exception occurred while processing the request. NeoException: SyntaxException: Type mismatch: expected List, List or List but was List (line 6, column 30 (offset: 327)) CALL algo.similarity.jaccard(p1Catalog, p2Catalog)

由 neo4jClient 构建的密码查询与顶部的原始查询有很大不同:

MATCH (p1:Book{friendlyUrl:'harry-potter-and-the-deathly-hallows'})-[r:BOOK_ADDED_TO_CATALOG]->(catalog1:Catalog)
WITH p1, collect(id(catalog1)) AS p1Catalog
MATCH (p2:Book)-[:BOOK_ADDED_TO_CATALOG]->(catalog2:Catalog)
WHERE p1 <> p2
WITH p1, p1Catalog, p2, collect(id(catalog2)) AS p2Catalog
CALL algo.similarity.jaccard(p1Catalog, p2Catalog)
YIELD value AS similiarity
RETURN p1 AS bk, p2 AS bk2
LIMIT 10

好的,所以这有两个部分 - 为什么 Cypher 不匹配,以及错误意味着什么 - 它们都是相关的,但我们将首先解决 Cypher 的差异 - 因为那会得到你的结果。

在您的 Cypher 中,您不做 CALL - 您只是 RETURN Jaccard,因此要真实反映您的 Cypher,您需要:

var result = _graphClient.Cypher
    .Match ("(p1:Book{friendlyUrl:'a-modern-witch'})-[r:BOOK_ADDED_TO_CATALOG]->(catalog1:Catalog)")
    .With ("p1, collect(id(catalog1)) AS p1Catalog")
    .Match ("(p2:Book)-[:BOOK_ADDED_TO_CATALOG]->(catalog2:Catalog)")
    .Where ("p1 <> p2")
    .With ("p1, p1Catalog, p2, collect(id(catalog2)) AS p2Catalog")
    .Return ((p1, p2, similiarity) => new {
      bk1 = p1.As<BookDetailsDto> (),
      bk2 = p2.As<BookDetailsDto> (),
      similarity = Return.As<double>("algo.similarity.jaccard(p1Catalog, p2Catalog)")
    })
    .OrderByDescending("similarity")
    .Limit (10);

其中的关键位是删除 .Call 错误、调用以及使用 Return.As<> 进行算法调用。

第二部分——(你得到的错误消息)与这个微妙的变化直接相关,通过使用 CALL 你从使用 Jaccard 的 'Function' 版本切换到 'Prodedure' 版本 - 它们有不同的签名,函数版本如下所示:

"algo.similarity.jaccard(vector1 :: LIST? OF NUMBER?, vector2 :: LIST? OF NUMBER?) :: (FLOAT?)"

所以它期望 LIST? OF NUMBER? 你的 COLLECT(id(catalog)) 输出。您可以在浏览器中通过 运行 以下 Cypher 获取此信息:

CALL dbms.functions() YIELD name, signature, description
WHERE name CONTAINS 'jaccard'
RETURN *

现在,Prodedure 版本如下所示:

"algo.similarity.jaccard(data = null :: LIST? OF MAP?, config = {} :: MAP?) :: (nodes :: INTEGER?, sourceNodes :: INTEGER?, targetNodes :: INTEGER?, similarityPairs :: INTEGER?, computations :: INTEGER?, write :: BOOLEAN?, writeRelationshipType :: STRING?, writeProperty :: STRING?, min :: FLOAT?, max :: FLOAT?, mean :: FLOAT?, stdDev :: FLOAT?, p25 :: FLOAT?, p50 :: FLOAT?, p75 :: FLOAT?, p90 :: FLOAT?, p95 :: FLOAT?, p99 :: FLOAT?, p999 :: FLOAT?, p100 :: FLOAT?)"

正在寻找 LIST? OF MAP? - 这 不是 您得到的 - 因此出现错误消息。

密码是:

CALL dbms.procedures() YIELD name, signature, description
WHERE name CONTAINS 'jaccard'
RETURN *

Anyhews - 第一个 C# 代码应该让你排序。