#!/usr/bin/env python # -*- coding: utf-8 -*- from __future__ import unicode_literals, absolute_import, print_function from gm_rpcd.all import bind import logging import traceback import json from search.utils.topic import TopicUtils from trans2es.models.topic import TopicHomeRecommend from libs.es import ESPerform from libs.cache import redis_client from search.utils.common import * from libs.es import ESPerform from django.conf import settings def get_discover_page_topic_ids(user_id, device_id, size, query_type=TopicPageType.FIND_PAGE): try: if user_id == -1: redis_key = "physical:discover_page" + ":user_id:" + str(user_id) + ":device_id:" + device_id else: redis_key = "physical:discover_page" + ":user_id:" + str(user_id) redis_field_list = [b'have_read_topic_id'] redis_field_val_list = redis_client.hmget(redis_key, redis_field_list) have_read_topic_id_list = json.loads(redis_field_val_list[0]) if redis_field_val_list[0] else [] recommend_topic_ids = TopicUtils.get_recommend_topic_ids(user_id=user_id, tag_id=0, offset=0, size=size,single_size=size, query_type=query_type, filter_topic_id_list=have_read_topic_id_list,index_type="topic",routing="4,5,6") have_read_topic_id_list.extend(recommend_topic_ids) redis_dict = { "have_read_topic_id": json.dumps(have_read_topic_id_list) } redis_client.hmset(redis_key, redis_dict) return recommend_topic_ids except: logging.error("catch exception,err_msg:%s" % traceback.format_exc()) return [] def get_home_recommend_topic_ids(user_id, device_id, tag_id, offset, size, query=None, query_type=TopicPageType.HOME_RECOMMEND): try: if query is None: if user_id>0: redis_key = "physical:home_recommend" + ":user_id:" + str(user_id) + ":query_type:" + str(query_type) else: redis_key = "physical:home_recommend" + ":device_id:" + device_id + ":query_type:" + str(query_type) else: if user_id>0: redis_key = "physical:home_query" + ":user_id:" + str(user_id) + ":query:" + str(query) + ":query_type:" + str(query_type) else: redis_key = "physical:home_query" + ":device_id:" + device_id + ":query:" + str(query) + ":query_type:" + str(query_type) redis_field_list = [b'have_read_topic_list'] redis_field_val_list = redis_client.hmget(redis_key, redis_field_list) # 获取已读帖子 have_read_topic_id_list = list() if redis_field_val_list[0]: if query is None: have_read_topic_id_list = list(json.loads(redis_field_val_list[0])) else: if offset>0: # 首次搜索时不需要过滤已读 have_read_topic_id_list = list(json.loads(redis_field_val_list[0])) # user_similar_score_redis_key = "physical:user_similar_score:user_id:" + str(user_id) # redis_user_similar_score_redis_val = redis_client.get(user_similar_score_redis_key) # user_similar_score_redis_list = json.loads( # redis_user_similar_score_redis_val) if redis_user_similar_score_redis_val else [] attention_tag_list = list() recommend_topic_list = list() if query is None: # linucb 推荐帖子 topic_recommend_redis_key = "physical:linucb:topic_recommend:device_id:" + str(device_id) recommend_topic_dict = redis_client.hgetall(topic_recommend_redis_key) if b"data" in recommend_topic_dict: recommend_topic_id_list = json.loads(recommend_topic_dict[b"data"]) # 推荐帖子是强插的,要保证推荐帖子不在已读里 recommend_topic_id_list = list(set(recommend_topic_id_list) - set(have_read_topic_id_list)) cursor = int(str(recommend_topic_dict[b"cursor"], encoding="utf-8")) newcursor = cursor + 6 if len(recommend_topic_id_list) > newcursor: recommend_topic_list = recommend_topic_id_list[cursor:newcursor] redis_client.hset(topic_recommend_redis_key, "cursor", newcursor) recommend_topic_user_list = list() if b"datadict" in recommend_topic_dict: recommend_topic_id_dict = json.loads(recommend_topic_dict[b"datadict"]) if len(recommend_topic_list) == 6: for i in recommend_topic_list: recommend_topic_user_list.append(recommend_topic_id_dict[str(i)]) # 用户关注标签 redis_tag_data = redis_client.hget("physical:linucb:register_user_tag_info", user_id) attention_tag_list = json.loads(redis_tag_data) if redis_tag_data else [] if len(recommend_topic_list)>0: size = size-len(recommend_topic_list) have_read_topic_id_list.extend(recommend_topic_list) # have_read_topic_id_list_add_promote = list() # have_read_topic_id_list_add_promote.extend(have_read_topic_id_list) # promote_recommend_topic_id_list = TopicHomeRecommend.objects.using(settings.SLAVE_DB_NAME).filter( # is_online=1).values_list("topic_id",flat=True) # # for topic_id in promote_recommend_topic_id_list: # have_read_topic_id_list_add_promote.append(topic_id) topic_id_list = list() rank_topic_id_list = TopicUtils.get_recommend_topic_ids(user_id=user_id, tag_id=tag_id, offset=0, size=size, single_size=size,query=query, query_type=query_type, filter_topic_id_list=have_read_topic_id_list, index_type="topic-high-star",routing="4,5,6",attention_tag_list=attention_tag_list,linucb_user_id_list=recommend_topic_user_list) if len(recommend_topic_list) == 6 and query is None: if (size < 11): topic_id_list.extend(rank_topic_id_list[0:3]) topic_id_list.extend(recommend_topic_list[0:3]) topic_id_list.extend(rank_topic_id_list[3:size]) topic_id_list.extend(recommend_topic_list[3:6]) else: topic_id_list.extend(rank_topic_id_list[0:size - 7]) topic_id_list.extend(recommend_topic_list[0:3]) topic_id_list.extend(rank_topic_id_list[size - 7:size]) topic_id_list.extend(recommend_topic_list[3:6]) else: topic_id_list.extend(rank_topic_id_list) have_read_topic_id_list.extend(topic_id_list) if len(have_read_topic_id_list) > 30000: cut_len = len(have_read_topic_id_list)-30000 have_read_topic_id_list = have_read_topic_id_list[cut_len:] redis_dict = { "have_read_topic_list": json.dumps(have_read_topic_id_list), } redis_client.hmset(redis_key, redis_dict) # 每个session key保存30天 redis_client.expire(redis_key, 60 * 60 * 24 * 30) return topic_id_list except: logging.error("catch exception,err_msg:%s" % traceback.format_exc()) return [] @bind("physical/search/query_tag_id_by_topic") def query_tag_id_by_topic(offset=0, size=10, topic_id_list=[], user_id=-1): try: return TopicUtils.get_topic_tag_info(offset, size, topic_id_list, user_id) except: logging.error("catch exception,err_msg:%s" % traceback.format_exc()) return {} @bind("physical/search/home_recommend") def home_recommend(device_id="", user_id=-1, offset=0, size=10, query_type=TopicPageType.HOME_RECOMMEND): """ :remark:首页推荐,目前只推荐日记 :param session_id: :param user_id: :param offset: :param size: :return: """ try: if not user_id: user_id = -1 if not isinstance(device_id, str): device_id = "" recommend_topic_ids = list() es_node_load_high_flag = False # try: # es_node_load_high_flag = ESPerform.if_es_node_load_high(ESPerform.get_cli()) # except: # logging.error("catch exception,err_msg:%s" % traceback.format_exc()) # es_node_load_high_flag = True if es_node_load_high_flag: temp_downgrading_key = "physical:home_recommend:user_id:241407656:query_type:1" redis_field_list = [b'have_read_topic_list'] redis_field_val_list = redis_client.hmget(temp_downgrading_key, redis_field_list) if redis_field_val_list[0]: have_read_topic_id_list = list(json.loads(redis_field_val_list[0])) if len(have_read_topic_id_list) > offset: recommend_topic_ids = have_read_topic_id_list[offset:offset+size] else: recommend_topic_ids = have_read_topic_id_list[0:size] else: recommend_topic_ids = get_home_recommend_topic_ids(user_id, device_id, tag_id=0, offset=0, size=size, query_type=query_type) return {"recommend_topic_ids": recommend_topic_ids} except: logging.error("catch exception,err_msg:%s" % traceback.format_exc()) return {"recommend_topic_ids": []} @bind("physical/search/discover_page") def discover_page(device_id="", user_id=-1, size=10): """ :remark:首页推荐,目前只推荐日记 :param session_id: :param user_id: :param offset: :param size: :return: """ try: if not user_id: user_id = -1 if not isinstance(device_id, str): device_id = "" recommend_topic_ids = get_discover_page_topic_ids(user_id, device_id, size, query_type=TopicPageType.FIND_PAGE) return {"recommend_topic_ids": recommend_topic_ids} except: logging.error("catch exception,err_msg:%s" % traceback.format_exc()) return {"recommend_topic_ids": []} @bind("physical/search/home_query") def home_query(device_id="", tag_id=-1, user_id=-1, query="", offset=0, size=10): """ :remark:首页搜索,目前只推荐日记 :param session_id: :param user_id: :param query: :param offset: :param size: :return: """ try: if not user_id: user_id = -1 if not isinstance(device_id, str): device_id = "" recommend_topic_ids = get_home_recommend_topic_ids(user_id, device_id, tag_id, offset=offset, size=size, query=query) return {"recommend_topic_ids": recommend_topic_ids} except: logging.error("catch exception,err_msg:%s" % traceback.format_exc()) return {"recommend_topic_ids": []} @bind("physical/search/topic_detail_page_recommend") def topic_detail_page_recommend(device_id="", user_id=-1, topic_id=-1, topic_pictorial_id=-1, topic_user_id=-1, filter_topic_user_id=False, offset=0, size=10, topic_tag_list=[]): """ :remark:帖子详情页推荐策略,缺少第一个卡片策略 :param user_id: :param topic_id: :param topic_group_id: :param topic_user_id: :return: """ try: if not isinstance(user_id, int): user_id = -1 if user_id > 0: redis_key = "physical:topic_detail_recommend" + ":user_id:" + str(user_id) + "topic_id:"+str(topic_id) else: redis_key = "physical:topic_detail_recommend" + ":device_id:" + device_id + "topic_id:"+str(topic_id) if int(offset) == 0: have_read_topic_list = list() # redis_dict = { # "have_read_topic_id": json.dumps(have_read_topic_list) # } redis_client.delete(redis_key) # redis_client.expire(redis_key, 60 * 60 * 24) else: have_read_topic_list = list() redis_field_list = [b'have_read_topic_list'] have_read_topic_redis_data = redis_client.hmget(redis_key,redis_field_list) have_read_topic_list = json.loads(have_read_topic_redis_data[0]) if have_read_topic_redis_data[0] else [] es_cli_obj = ESPerform.get_cli() have_read_topic_list.append(topic_id) topic_user_result = list() topic_tag_result = list() result = list() if len(topic_tag_list) != 0: topic_tag_result = TopicUtils.top_get_topic_detail_recommend_list(user_id,topic_id,have_read_topic_list,size,es_cli_obj, index_type="topic",routing="3,4,5,6",topic_tag_list = topic_tag_list) topic_tag_size = len(topic_tag_result) have_read_topic_list.extend(topic_tag_result) else: topic_tag_size = 0 if topic_tag_size 0: recommend_topic_ids_list = [item["_source"]["id"] for item in result_list] return {"recommend_topic_id": recommend_topic_ids_list} except: logging.error("catch exception,err_msg:%s" % traceback.format_exc()) return {"recommend_topic_id": []} @bind("physical/search/topic") def topic_search(filters, nfilters=None, sorts_by=None, offset=0, size=10): """帖子搜索。""" try: result_list = TopicUtils.list_topic_ids(filters=filters, nfilters=nfilters, sorts_by=sorts_by, offset=offset, size=size) logging.info("get result_list:%s"%result_list) topic_ids = [item["_source"]["id"] for item in result_list["hits"]] return { "topic_ids": topic_ids, "total_count": result_list["total_count"] } except: logging.error("catch exception, err_msg:%s" % traceback.format_exc()) return {"topic_ids": [], "total_count": 0} @bind("physical/search/query_topic_by_user_similarity") def query_topic_by_user_similarity(topic_similarity_score_dict, offset=0, size=10): """ :remark 按帖子所属用户相似度召回帖子 :param tag_id: :param offset: :param size: :return: """ try: must_topic_id_list = list(topic_similarity_score_dict.keys()) topic_id_list = TopicUtils.get_recommend_topic_ids(tag_id=0, user_id=-1, offset=offset, size=size,single_size=size, must_topic_id_list=must_topic_id_list,index_type="topic",routing="4,5,6") return {"recommend_topic_ids": topic_id_list} except: logging.error("catch exception,err_msg:%s" % traceback.format_exc()) return {"recommend_topic_id": []}