我有一个数据库,其中已经保存了一些:Post
和:HashTag
节点。
:Post
节点具有属性id
和text
。 :HashTag
节点具有属性id
和tag
(标记为HashTag
的名称或文本)。
:HashTag
节点均为小写,并以#
开头。
我想编写一个查询,每当我在其中创建包含数据库中当前Post
的新HashTag
时,它都会自动在的HashTag
属性中找到text
:Post
节点并建立这样的关系:
(:Post)<-[:TAG]-(:HashTag)
例如,我正在创建:Post
:
Today is #friday, ready for the #weekend
我的数据库中有weekend
hashTag,但没有friday
。
因此,我将在此TAG
和:Post
hashTag之间建立一个关系weekend
,而与friday
hashTag无关。
但是如果我有这个:Post
:
Chrismats #holiday , and #traveling
在这里,我在数据库中同时拥有#holiday
和#traveling
,并且:HashTag
也与此TAG
和{{1} }以及此:Post
和#holiday
TAG
关系
有什么主意该如何编写此查询?
答案 0 :(得分:1)
您需要在此处进行一些文本处理,首先在空白处使用split()
获取单词列表,仅过滤以'#'开头的单词,然后清除单词(转换为小写字母)并删除标点符号和非字母数字字符)。您需要APOC Procedures才能使用clean函数
您可以在列表上进行UNWIND(这样每个单词都将在其自己的行上),匹配到具有给定名称的:HashTag节点,并创建关系。
... // assume you just created post:Post with text, with post and text still in scope
WITH post, [tag in split(text, ' ') WHERE tag STARTS WITH '#' | apoc.text.clean(tag)] as tagWords
UNWIND tagWords as tagWord
MATCH (tag:HashTag {tag:tagWord})
CREATE (tag)-[:TAG]->(post)
答案 1 :(得分:0)
答案是https://stackoverflow.com/a/54661113/9161843,因为我正在通过代码搜索解决方案:
function getHashTags(postText) {
const regex = /#[^\s!$%^&*+.,£#]+/gm;
const selectedHashTag = [];
const subStr = postText.split(' ');
const checkHashTag = _.filter(subStr, word => word.startsWith('#') || word.includes('#'));
checkHashTag.map((hashTags) => {
if (hashTags.match(regex)) {
hashTags.match(regex).map(hashTag => selectedHashTag.push(hashTag.substr(1)));
}
return true;
});
return selectedHashTag;
}