召回模塊:用戶推薦邏輯完善

日萌社

人工智能AI:Keras PyTorch MXNet TensorFlow PaddlePaddle 深度學習實戰(不定時更新)


2.6 用戶推薦邏輯完善

學習目標

  • 目標
    • 瞭解用戶推薦緩存獲取邏輯
    • 知道用戶行爲數據讀取操作
  • 應用
    • 應用完成用戶推薦緩存獲取代碼
    • 應用完成用戶行爲數據neo4j行爲讀寫操作

2.6.1 用戶推薦緩存獲取

之前提供了一個這樣的接口,用戶獲取用戶緩存結果推薦出去,這裏會用到用戶的IP進行判斷

  • get_cache

根據用戶請求,獲取用戶緩存結果(進行用戶是否第一次使用某IP登陸判斷)

@api_view(['GET', 'POST'])
def get_cache(request):
    IP = request.META.get("HTTP_X_REAL_IP")
    result = r_api.v_get_cache(str(IP))
    return HttpResponse(json.dumps(result, ensure_ascii=False))

實現步驟:

  • 判斷用戶是否第一次使用這個IP登錄
    • 如果是,判斷用戶IP對應緩存是否爲空
      • 爲空:進行召回、排序過程推薦出去_get_recomm
      • 不爲空:直接進行緩存結果獲取(會自動刪除獲取的這些結果)
def v_get_cache(IP):
    r = redis.StrictRedis(connection_pool=pool)
    # 判斷該用戶是否第一次使用這個IP登錄
    uid = r.get("u_" + IP)
    if not uid:
        uid = random.choice([10033736])
        r.set("u_" + IP, uid)

    # 判斷IP對應的緩存是否爲空
    if not r.llen(IP):
        return _get_recomm(IP, int(uid))
    else:
        pid_list = eval(r.lpop(IP))
        print(pid_list)
        with _driver.session() as session:
            cypher = "match(a:SuperfansPost{pid:%d}) return properties(a)"

            record = list(map(lambda x: session.run(cypher % x), pid_list))
            result = list(
                map(lambda y: list(map(lambda x: x[0], y))[0], record))
        return result

2.6.2 用戶操作行爲API

用戶點贊API、用戶評論API、用戶轉發API、用戶取消點贊API、用戶刪除評論API。我們會對用戶的操作進行數據庫的節點增刪改查。主要是對用戶的行爲關係進行修改

@api_view(['GET', 'POST'])
def like(request):
    IP = request.META.get("HTTP_X_REAL_IP")
    pid = request.POST.get("pid")
    type_ = "like"
    result = api.write_to_neo4j(IP, pid, type_)
    return Response(result)


@api_view(['GET', 'POST'])
def forward(request):
    IP = request.META.get("HTTP_X_REAL_IP")
    pid = request.POST.get("pid")
    type_ = "forward"
    result = api.write_to_neo4j(IP, pid, type_)
    return Response(result)


@api_view(['GET', 'POST'])
def comment(request):
    IP = request.META.get("HTTP_X_REAL_IP")
    pid = request.POST.get("pid")
    content = request.POST.get("content")
    type_ = "comment"
    result = api.write_to_neo4j(IP, pid, type_, content)


@api_view(['GET', 'POST'])
def cancel_like(request):
    IP = request.META.get("HTTP_X_REAL_IP")
    pid = request.POST.get("pid")
    type_ = "like"
    result = api.cancel_to_neo4j(IP, pid, type_)

2.6.2.1 neo4j數據庫讀寫邏輯代碼實現

  • 1、用戶點贊後寫數據庫,我們將匹配用戶節點,和帖子節點,並在兩者之間合併一條類似類型的邊,合併是指:存在則匹配,不存在則創建。
  • 2、用戶評論後的寫數據庫,同樣匹配用戶和帖子節點,並在兩者之間創建一條表示類型的邊,並且爲邊置於時間和內容屬性。以便在刪除操作時進行索引。
  • 3、用戶轉發操作的寫數據庫,同樣匹配用戶和帖子節點,並在兩者之間創建一條共享類型的邊。
  • 4、用於用戶的取消點讚的操作,匹配用戶和帖子節點,並刪除他們之間像類型的邊。
  • 5、用於用戶的刪除評論操作,匹配用戶和帖子節點,根據時間戳刪除指定的讚揚類型的邊。
cypher1 = "MATCH(a:{uid:%d}) MATCH(b:SuperfansPost{pid:%d}) with a,b MERGE(a)-[r:%s]-(b)"
cypher2 = "MATCH(a:SuperfansUser{uid:%d}) MATCH(b:SuperfansPost{pid:%d}) with a,b CREATE(a)-[r:%s]-(b) set r.time=%d, r.content=%s"
cypher3 = "MATCH(a:SuperfansUser{uid:%d}) MATCH(b:SuperfansPost{pid:%d}) with a,b CREATE(a)-[r:%s]-(b)"
cypher4 = "MATCH(a:SuperfansUser{uid:%d})-[r:%s]-(b:SuperfansPost{pid:%d}) delete r"
cypher5 = "MATCH(a:SuperfansUser{uid:%d})-[r:%s]-(b:SuperfansPost{pid:%d}) where r.time=%d delete r

1、寫入數據行爲邏輯

r_result = {"msg":"Success", "code":1}
f_result = {"msg": "Fail", "code":0}

def write_to_neo4j(IP, pid, type_, content=""):
    """寫入行爲類型到neo4j數據庫
    :param IP: 用戶IP
    :param pid: 帖子ID
    :param type_: 行爲類型
    :param content: 內容(評論)
    :return:
    """
    r = redis.StrictRedis(connection_pool=pool)
    uid = r.get("u_" + IP)
    # 如果類型是喜歡,寫入喜歡關係
    if type_ == "like":
        # 判斷是否存在該用戶,存在寫入,返回成功,不存在返回失敗
        if uid:
            with _driver.session() as session:
                session.run(cypher1 % (int(uid), int(pid), type_))
                return r_result
        else:
            return f_result
    elif type_ == "comment":
        if uid:
            time_ = int(time.time())
            with _driver.session() as session:
                session.run(cypher2 % (int(uid), int(pid), type_, time_, content))
                return r_result
        else:
            return f_result
    else:
        if uid:
            with _driver.session() as session:
                session.run(cypher3 % (int(uid), int(pid), type_))
            return r_result
        else:
            return f_result

2、取消行爲類型

def cancel_to_neo4j(IP, pid, type_, time_):
    """
    刪除行爲類型
    :param IP: 用戶IP
    :param pid: 帖子ID
    :param type_: 行爲類型
    :param time_: 時間戳
    :return:
    """
    r = redis.StrictRedis(connection_pool=pool)
    uid = r.get("u_" + IP)
    if type_ == "like":
        if uid:
            with _driver.session() as session:
                session.run(cypher4 %(int(uid), type_, int(pid)))
                return r_result
        else:
            return f_result
    # 如果是評論取消
    elif type_ == "comment":
        if uid:
            # 根據時間戳刪除
            with _driver.session() as session:
                session.run(cypher5 %(int(uid),type_, int(pid), time_))
                return r_result
        else:
            return f_result

2.6.3 小結

  • 用戶推薦緩存獲取代碼

  • 用戶行爲數據neo4j行爲讀寫操作

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章