日萌社
人工智能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
- 不爲空:直接進行緩存結果獲取(會自動刪除獲取的這些結果)
- 如果是,判斷用戶IP對應緩存是否爲空
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行爲讀寫操作