我试图在过去24小时内找到人 近到用户的最后位置一个简单的推荐引擎。我的数据集很容易用于测试目的:
我的查询有什么问题?它多次回复用户Ayse,但我不想让同一个人两次或更多次。
以下是我的疑问:
var neo4j = require('neo4j-driver').v1;
var driver = neo4j.driver("bolt://localhost", neo4j.auth.basic("neo4j", "neo4j"));
var session = driver.session();
function runQuery(query) {
session.run(query, {}).then(function(result){
console.log("finish")
result.records.forEach(function(record) {
console.log(record._fields)
})
}).catch(console.log);
}
//runQuery("MATCH (n) DETACH DELETE n" )
function newUser(user) {
runQuery("CREATE (:User{name:'"+user+"'})")
}
function newLocation(user, lat, lon) {
var q =
"MATCH (u:User{name:'"+user+"'}) "+
"CREATE (l:Location{lat: "+lat+", lon: "+lon+", created_at: TIMESTAMP()}) "+
"CREATE (u)-[:HAVE_BEEN]->(l) "
runQuery(q)
}
/*
newUser("Ozgur")
newUser("Fatma")
newUser("Ayse")
*/
/*
newLocation("Ozgur", 38.134972, 26.96681)
newLocation("Ozgur", 37.239972, 25.96681)
newLocation("Ozgur", 38.334972, 16.96681)
*/
/*
newLocation("Ayse", 38.294972, 26.76681)
newLocation("Ayse", 37.639972, 25.66681)
newLocation("Ayse", 35.134972, 18.96681)
*/
/*
newLocation("Fatma", 31.114972, 21.76681)
newLocation("Fatma", 31.139972, 21.66681)
*/
function findUserRecommendation(user) {
// get user recommendations
var q =
"MATCH "+
//get user locations for last 24 hours (me_loc)
"(me:User{name:'"+user+"'})-[:HAVE_BEEN]->(me_loc:Location), " +
// strangers (recommendations)
"(l:Location)<-[:HAVE_BEEN]-(stranger:User) " +
"WHERE "+
//except me
"NOT me = stranger "+
// nearest location algorithm based on KM
"AND 2 * 6371 * "+
"asin("+
"sqrt("+
"haversin(radians(me_loc.lat - l.lat)) + "+
"cos(radians(me_loc.lat)) * "+
"cos(radians(l.lat)) * haversin(radians(me_loc.lon - l.lon))"+
")"+
// 500 km
") < 500 " +
// last 24 hours of they location
//"AND l.created_at > (TIMESTAMP() - 604800) "+
// last 24 hours of user's location
//"AND me_loc.created_at > (TIMESTAMP() - 604800)" +
// return every stranger's name and last location once
// but returning Ayse's name and different location more than once
"RETURN DISTINCT stranger.name, l.lat, l.lon"
runQuery(q)
}
findUserRecommendation("Ozgur")
答案 0 :(得分:2)
DISTINCT
只会确保您不会获得重复的结果行,它不会限制您到每个DISTINCT
元素的第一行(它实际上适用于所有非{行中的聚合元素作为一个单元,就像使用元组作为键一样)。你必须聚合lat / long然后找出它们中的哪一个。假设您只需要任何单个纬度/经度,请尝试使用此代替返回线:
WITH stranger, COLLECT(l) AS locs
WITH stranger, HEAD(locs) AS l
RETURN stranger.name, l.lat, l.lon
如果您想根据特定条件(例如最近或最接近的标准)挑选单个纬度/经度,则可以将HEAD()
来电替换为REDUCE()
。