假设我们拥有100,000人的集合,每个人都有一个属性列表,例如:
height: "between 130 and 140 cm"
eyecolor: "blue"
age_rangee: "16-18"
favorite_music_type: "jazz"
home_city: "NYC"
owns_a_boat: "no"
preferred_flower: "hyacinth"
bathing_frequency_per_month: 60
car_type: "minivan"
house_type: "apartment"
wears_jeans: "often"
wears_sandals: "never"
wears_boots: "sometimes"
属性集可能因人而异。属性的数量可以更改,属性的类型可能会更改。当然,属性的价值可能会发生变化。但是,给定一个人,我们假设他的属性与我们馆藏中的一些人有一些重叠。
我的问题是:“表达这些不同的最佳方式是什么? 图表数据库中的属性,以便我可以最快速地选择一组50人,其属性最类似地匹配特定个人的属性,并从最佳匹配到最差匹配排序“
谢谢肯尼,
在您的Cypher查询示例中,我是否了解每个要素节点都包含一个键:值 标识属性的对和它的对应值?
这是一个更复杂的同余匹配问题。
假设我们有一个功能集,(A,B,C,D,E,F)和100,000 具有与此偏好设定的某种程度匹配的偏好的人。 但每个功能,不仅可能有偏好,但他们可能没有偏好。
例如Lena的偏好是,(A,B,C,X,Y,Z)和 罗伯特的偏好是,(A,B,C,_,_,),(在underbar,(),表示任何选择都可以)
我们想在偏好匹配方面对罗伯特的评价高于莉娜,因为尽管如此 他和Lena拥有相同数量的匹配偏好,Robert的错配匹配偏好更少
这是一个更具体的例子:
假设我们有10万人对汽车感兴趣,我们知道汽车的哪些特征对他们很重要。 比方说,我们拥有10辆具有各种功能的汽车,我们希望选择一组50人,他们想要的汽车功能最好 匹配10辆车中的每一辆。
有些人对所有汽车功能的子集没有偏好。 例如Lester在传输方面没有偏好,无论是“自动”还是“手动”,都可以, 而Rebecca对'color','power_windows'和'power_door_locks'没有偏好。任何颜色都可以,并且 她不在乎汽车是否有电动车窗和门锁。
因此,例如,这是一辆具有一组已定义功能的汽车
engine: '4cylinder'
transmission: 'automatic'
color: 'dark blue'
size: 'subcompact'
age: 'less than 4 years'
power_windows: 'yes'
power_door_locks: 'yes'
average_gas_milage: 'greater than 30mpg'
在这里,我们有两个人,莱斯特和丽贝卡,他们已经表明了对他们很重要的特征:
莱斯特:
engine: '4cylinder'
color: 'dark blue'
size: 'subcompact'
age: 'less than 4 years'
power_windows: 'yes'
power_door_locks: 'yes'
average_gas_milage: 'greater than 30mpg'
丽贝卡:
engine: '4cylinder'
transmission: 'automatic'
size: 'subcompact'
age: 'less than 4 years'
average_gas_milage: 'greater than 30mpg'
那么我们如何才能最好地选择和订购一组50人,其特征偏好最适合每辆车? 在这种情况下,我们希望具有最大匹配功能首选项的人员排名第一, 但我们也想包括那些对任何特定属性值感到满意的人。
答案 0 :(得分:0)
好问题。首先,我建议参加免费的在线培训课程,该课程巧妙地向您介绍Neo4j和Cypher查询语言背后的基本概念:http://www.neo4j.org/training
您的问题是一个简单的数据建模练习我很乐意引导您完成。在将数据建模为图形时,类的某些属性或属性(例如人)可以将它们自身表示为节点。
通过查看类person
的一些示例数据,您当然会注意到属性值的一些冗余。这些重叠允许我们在该类上进行选择,并通过共享属性对结果进行分组。在大多数数据库中这很容易做到。 Neo4j允许您做的是采用属于一个人的任意一组功能,然后根据这些共享功能选择所有相似的人。
MATCH (john:Person {name: "John Doe"})-[:HAS_FEATURE]->(feature),
(feature)<-[:HAS_FEATURE]-(people)
WITH john, count(DISTINCT feature) as feature_count, people
RETURN john.name, people.name, feature_count
ORDER BY feature_count DESC
此查询查找名为John Doe
的人以及属于他的所有功能。每个要素都是一个节点,表示可归因于某个人的值。每个功能都是唯一的,作为单个节点,并将人们组合在一起。
然后,查询会找到与people
共享feature
的所有john
。然后在WITH
子句中,查询计算john
与每个人共享的功能。最后,查询返回john
的名称,他共享的人的姓名以及他们共享的功能数量。然后查询按feature_count
降序排序。
这将返回与John Doe共享最多功能的人。
答案 1 :(得分:0)
另请查看"Matches are the new Hotness"和"Match Making with Neo4j"博客文章,了解如何将节点的部分子图相互连接的示例。
START me=node:users_index(name={user})
MATCH skills<-[:has]-me-[:lives_in]->city<-[:in_location]-job-[:requires]->requirements
WHERE me-[:has]->()<-[:requires]-job
WITH DISTINCT city.name AS city_name,
job.name AS job_name,
LENGTH(me-[:has]->()<-[:requires]-job) AS matching_skills,
LENGTH(job-[:requires]->()) AS job_requires,
COLLECT(DISTINCT requirements.name) AS req_names,
COLLECT(DISTINCT skills.name) AS skill_names
RETURN city_name, job_name,
FILTER(name IN req_names WHERE NOT name IN skill_names) AS missing
ORDER BY matching_skills / job_requires DESC, job_requires
LIMIT 10
和
START me=node:users_index(name={user})
MATCH me-[:lives_in]->city<-[:lives_in]-person
WHERE me.orientation = person.orientation AND
((me.gender <> person.gender AND me.orientation = "straight") OR
(me.gender = person.gender AND me.orientation = "gay")) AND
me-[:wants]->()<-[:has]-person AND
me-[:has]->()<-[:wants]-person
WITH DISTINCT city.name AS city_name, person, me
MATCH me-[:wants]->attributes<-[:has]-person-[:wants]->requirements<-[:has]-me
RETURN city_name, person.name AS person_name,
COLLECT(attributes.name) AS my_interests,
COLLECT(requirements.name) AS their_interests,
COUNT(attributes) AS matching_wants,
COUNT(requirements) AS matching_has
ORDER BY matching_wants / (1.0 / matching_has) DESC
LIMIT 10