我知道这听起来可能是胡说八道,但我会尽力解释我所面对的neo4jClient问题。
我开发了Social TaskManagment软件。对于服务器端代码和数据存储,我选择使用neo4j(neo4jClient)和C#。
在我们的软件中想象一个用户:(mhs)发布的任务“@ somebody请帮助我#Neo4j #cypher”任务将装饰一些花哨的角色,包括(@#+ /)obove post将在neo4j中保存为如下图:
(post:Post {Text : @somebody please help me on #Neo4j})-[Has_HashTag]-(neo4j:HashTag)
(post:Post)-[Has_HashTag]-(Cypher: HashTag)
(post:Post)-[Has_Author)-[mhs:User]
(post:Post)-[Has_MentionedUser)-[Somebody:User]
现在想象用户@mhs正在尝试搜索#Neo4j的HashTag并向@somebody提及的帖子
这里我正在构建(手工制作)Cypher查询,其中包括Cypher中的2个参数参数以及一些花哨的C#代码,这些代码导致了Cypher查询:
MATCH (nodes)-[r]-(post:Post),
(post:Post)-[:HAS_MentionedUsers]->(assignee1307989068:User),
(nodes)-[r]-(post:Post)-[:HAS_HashTags]->(Hashtag1482870844:HashTag)
WHERE (assignee1307989068.UserName = "somebody") AND (Hashtag1482870844.Value = "neo4j")
RETURN post AS Post, Collect(nodes) as nodes
ORDER BY post.creationDate
上面的cypher将返回一个帖子,其中只包含帖子中未包含在Where子句中的所有节点。 我的问题是如何包含与Targeted(post)相关的所有节点,而不将它们包含在cypher的Return部分中。像return(*)。
其他问题是如何将结果集反序列化为C#而不知道它可能具有什么形状。
我正在制作上述Cypher的搜索方法是休闲的:
public List<PostNode> Search(string searchterm)
{
List<string> where = new List<string>();
var tokenizedstring = searchterm.Split(' ');
var querystring = new StringBuilder();
var relatedNodes = new List<string>();
var q = new CypherFluentQuery(_graphClient) as ICypherFluentQuery;
foreach (var t in tokenizedstring)
{
_commandService.BuildPostQueystring(t, ref querystring, ref where, ref relatedNodes);
}
if (querystring[querystring.Length - 1] == ',')
querystring = querystring.Remove(querystring.Length - 1, 1);
q = q.Match(querystring.ToString());
int i = 1;
if (where.Count > 0)
q = q.Where(where[0]);
while (i < where.Count)
{
q = q.AndWhere(where[i]);
i++;
}
var rq = q.Return(
(post, nodes) => new PostNode
{
Post = post.As<Node<string>>(),
Nodes = nodes.CollectAs<string>()
})
.OrderBy("post.creationDate");
var results = rq.Results.ToList();
//foreach (var result in results)
//{
// //dynamic p = JsonConvert.DeserializeObject<dynamic>(result.Post.Data);
// //dynamic d = JsonConvert.DeserializeObject<dynamic>(result.Nodes.Data);
//}
return results;
}
}
//Some Helper Class just to cast the result.
public class PostNode
{
public Node<string> Post { get; set; }
public IEnumerable<Node<string>> Nodes { get; set; }
}
但是您可能已经注意到它没有通过Cypher Query中的Where子句包含在搜索词中的节点。 我真的在这里停留了一段时间,因为我无法为此提供任何合适的解决方案。所以你的帮助可以为我节省很多。 可能是我完全走错了路,所以请以任何你能想到的方式提供帮助。
答案 0 :(得分:3)
似乎正在配置UNKNOWN相关节点的列表,因此其中一个:
情景A
这些相关节点究竟是什么并不重要,我只想要它们。
问题:检索那些未知但相关的节点的意图是什么?通过回答这个机会,这个问题可以很好地改进。
情景B
这些未知的相关节点实际上是已知的!它只是在查询执行时并不完全知道,但是在C#代码的某个地方,我们会有这样的事情
if (nodes.Any(_ => _ is HashTag) {...}
问题:
这种行为需要知道类型。即使使用反射或C#动态的东西,要求仍然存在,因为Neo4jClient无法将来自Neo4j的一包JSON数据关联到任何本地类型。当Neo4jClient以某种方式通过线路接收大量数据时,它应该知道您更喜欢用什么类型来表示。这就是查询总是这样的原因:
Return((a, p) => new
{
Author = a.As<Author>(), //we expect node content to be represented as Author
Post = p.As<Post>()
})
Neo4jClient 不会在Neo4j数据库中保留C#类型。这样做本来是很讨厌的。然而,背后的想法是你不应该发现自己迫不及待,如果你这样做,那么我会建议在其他地方寻找问题,即为什么你会依靠你的客户端库为你描述你的域名?