找到靠近用户最后位置的人

时间:2016-11-01 18:21:48

标签: neo4j

我试图在过去24小时内找到 到用户的最后位置一个简单的推荐引擎。我的数据集很容易用于测试目的:

enter image description here

我的查询有什么问题?它多次回复用户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")

1 个答案:

答案 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()