SearchCacheService.java 5.15 KB
package com.yoho.search.cache.beans;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.yoho.core.redis.cluster.operations.serializer.RedisKeyBuilder;
import com.yoho.search.base.utils.MD5Util;
import com.yoho.search.cache.model.CacheObject;
import com.yoho.search.cache.model.SearchCache;
import com.yoho.search.common.SearchServiceConfiger;
import com.yoho.search.core.es.model.SearchParam;
import com.yoho.search.core.es.utils.SearchParamUtils;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.lang.reflect.Type;

@Service
public class SearchCacheService {

	@Autowired
	private SearchServiceConfiger searchServiceConfiger;

	private void addObjectToCache(RedisKeyBuilder redisKeyBuilder, Object object, SearchCache searchCache) {
		// 1、如果不适用缓存,则直接返回
		if (!searchServiceConfiger.useCache()) {
			return;
		}
		// 2、如果缓存不存在,则直接返回
		if (searchCache == null || searchCache.getCache() == null) {
			return;
		}
		// 3、加入缓存
		CacheObject cacheObject = null;
		if (object instanceof JSONObject) {
			cacheObject = new CacheObject((JSONObject) object);
		} else if (object instanceof JSONArray) {
			cacheObject = new CacheObject((JSONArray) object);
		} else {
			cacheObject = new CacheObject(object);
		}
		searchCache.getCache().addOrUpdate(redisKeyBuilder, cacheObject, searchCache.getCacheInMinute());
	}

	/**
	 * 从缓存中取数据
	 * 
	 * @param redisKeyBuilder
	 * @return
	 */
	private CacheObject getCacheObjectFromCache(RedisKeyBuilder redisKeyBuilder, SearchCache searchCache) {
		// 1、如果不适用缓存,则直接返回
		if (!searchServiceConfiger.useCache()) {
			return null;
		}
		// 2、如果缓存不存在,则直接返回
		if (searchCache == null || searchCache.getCache() == null) {
			return null;
		}
		// 3、增加缓存访问次数
		searchCache.incTotalCount();

		// 4、从缓存中获取cacheObject
		CacheObject cacheObject = searchCache.getCache().get(redisKeyBuilder);

		// 5、如果从缓存中拿不到数据,则直接返回
		if (cacheObject == null) {
			return null;
		}
		// 6、增加缓存命中次数,并返回缓存对象
		searchCache.incMatchCount();
		return cacheObject;
	}

	/*********************************** JSONObject *****************************************/
	public RedisKeyBuilder genSearchParamString(String indexName, SearchParam searchParam) {
		//1、拼装内容
		StringBuilder redisKeyValue = new StringBuilder();
		redisKeyValue.append("indexName:").append(indexName).append(';');
		redisKeyValue.append("searchType:").append(searchParam.getSearchType() == null ? "" : searchParam.getSearchType().name()).append(';');
		SearchSourceBuilder searchSourceBuilder = SearchParamUtils.genSearchSourceBuilderFromSearchParam(searchParam);
		redisKeyValue.append("searchSource:").append(searchSourceBuilder).append(';');

		//2、构建RedisKeyBuilder
		RedisKeyBuilder redisKeyBuilder = RedisKeyBuilder.newInstance();
		redisKeyBuilder.appendFixed("YOHOSEARCH:");
		redisKeyBuilder.appendFixed("DEFAULT1:");
		redisKeyBuilder.appendVar(MD5Util.string2MD5(redisKeyValue.toString()));
		return redisKeyBuilder;
	}

	public void addJSONObjectToCache(SearchCache searchCache, String indexName, SearchParam searchParam, JSONObject jsonObject) {
		RedisKeyBuilder key = this.genSearchParamString(indexName, searchParam);
		this.addObjectToCache(key, jsonObject, searchCache);
	}

	public JSONObject getJSONObjectFromCache(SearchCache searchCache, String indexName, SearchParam searchParam) {
		RedisKeyBuilder key = this.genSearchParamString(indexName, searchParam);
		CacheObject cacheObject = this.getCacheObjectFromCache(key, searchCache);
		if (cacheObject == null) {
			return null;
		}
		return cacheObject.toJSONObject();
	}

	/*********************************** object *****************************************/
	public <T> T getSerializableObjectFromCache(SearchCache searchCache, RedisKeyBuilder redisKeyBuilder, Type type, boolean useJsonSerializable) {
		try {
			CacheObject cacheObject = this.getCacheObjectFromCache(redisKeyBuilder, searchCache);
			if (cacheObject == null) {
				return null;
			}
			if (useJsonSerializable) {
				String stringValue = (String)cacheObject.toObject();
				return JSON.parseObject(stringValue, type);
			} else {
				return (T) cacheObject.getValue();
			}
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}

	public <T> void addSerializableObjectToCache(SearchCache searchCache, RedisKeyBuilder redisKeyBuilder, T object, boolean useJsonSerializable) {
		if (useJsonSerializable) {
			String jsonStr =  JSON.toJSONString(object,SerializerFeature.WriteMapNullValue,SerializerFeature.DisableCircularReferenceDetect);
			this.addObjectToCache(redisKeyBuilder, jsonStr, searchCache);
		} else {
			this.addObjectToCache(redisKeyBuilder, object, searchCache);
		}
	}
}