In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly introduces "how to use java and redis to achieve a simple hot search function". In daily operation, I believe many people have doubts about how to use java and redis to achieve a simple hot search function. Xiaobian consulted all kinds of materials and sorted out simple and easy-to-use methods of operation. I hope it will be helpful to answer the questions of "how to use java and redis to achieve a simple hot search function". Next, please follow the editor to study!
The following features are available:
1: the search bar displays the search history of the currently logged in individual user, and deletes the personal history.
2: if a user enters a character in the search bar, it will be recorded in the redis stored in zset format, and the number of characters searched and the current timestamp will be recorded (using the DFA algorithm, please learn from Baidu if you are interested)
3: whenever users query characters that already exist in redis, they directly add up the number to get the ten most popular queries on the platform. (you can write your own interface or directly add some prepared keywords to redis)
4: finally, we have to do indecent text filtering function. This is important. Forget it, you know.
Code to achieve hot search and personal search record function, the main controller layer under several methods on the line:
1: add a hot search vocabulary to redis (use the following indecent text filtering method to filter the word when adding it, and then store it legally
2: give the related words + 1 per click.
3: search for the top ten most relevant according to key
4: insert personal search record
5: query personal search records
First of all, configure the redis data source and so on.
Finally, paste the code of the core service layer:
Package com.****.user; import com.jianlet.service.user.RedisService;import org.apache.commons.lang.StringUtils;import org.springframework.data.redis.core.*;import org.springframework.stereotype.Service;import javax.annotation.Resource;import java.util.*;import java.util.concurrent.TimeUnit / * * @ author: mrwanghc * @ date: 2020-5-13 * @ description: * / @ Transactional@Service ("redisService") public class RedisServiceImpl implements RedisService {/ / Import data source @ Resource (name = "redisSearchTemplate") private StringRedisTemplate redisSearchTemplate / / add a new keyword @ Override public int addSearchHistoryByUserId (String userid, String searchkey) {String shistory = RedisKeyUtils.getSearchHistoryKey (userid); boolean b = redisSearchTemplate.hasKey (shistory); if (b) {Object hk = redisSearchTemplate.opsForHash (). Get (shistory, searchkey) If (hk! = null) {return 1;} else {redisSearchTemplate.opsForHash (). Put (shistory, searchkey, "1");}} else {redisSearchTemplate.opsForHash (). Put (shistory, searchkey, "1");} return 1 } / / Delete personal historical data @ Override public Long delSearchHistoryByUserId (String userid, String searchkey) {String shistory = RedisKeyUtils.getSearchHistoryKey (userid); return redisSearchTemplate.opsForHash () .delete (shistory, searchkey);} / / get personal historical data list @ Override public List getSearchHistoryByUserId (String userid) {List stringList = null; String shistory = RedisKeyUtils.getSearchHistoryKey (userid) Boolean b = redisSearchTemplate.hasKey (shistory); if (b) {Cursor cursor = redisSearchTemplate.opsForHash (). Scan (shistory, ScanOptions.NONE); while (cursor.hasNext ()) {Map.Entry map = cursor.next (); String key = map.getKey (). ToString (); stringList.add (key) } return stringList;} return null;} / / add a hot word search record to store @ Override public int incrementScoreByUserId (String searchkey) {Long now = System.currentTimeMillis (); ZSetOperations zSetOperations = redisSearchTemplate.opsForZSet (); ValueOperations valueOperations = redisSearchTemplate.opsForValue (); List title = new ArrayList () Title.add (searchkey); for (int I = 0, lengh = title.size (); I
< lengh; i++) { String tle = title.get(i); try { if (zSetOperations.score("title", tle) 9) {//只返回最热的前十名 break; } Long time = Long.valueOf(valueOperations.get(val)); if ((now - time) < 2592000000L) {//返回最近一个月的数据 result.add(val); } else {//时间超过一个月没搜索就把这个词热度归0 zSetOperations.add("title", val, 0); } } } }else{ for (String val : value) { if (result.size() >9) {/ / only return the top ten hottest break;} Long time = Long.valueOf (valueOperations.get (val)); if ((now-time))
< 2592000000L) {//返回最近一个月的数据 result.add(val); } else {//时间超过一个月没搜索就把这个词热度归0 zSetOperations.add("title", val, 0); } } } return result; } //每次点击给相关词searchkey热度 +1 @Override public int incrementScore(String searchkey) { String key = searchkey; Long now = System.currentTimeMillis(); ZSetOperations zSetOperations = redisSearchTemplate.opsForZSet(); ValueOperations valueOperations = redisSearchTemplate.opsForValue(); zSetOperations.incrementScore("title", key, 1); valueOperations.getAndSet(key, String.valueOf(now)); return 1; } } 核心的部分写完了,剩下的需要你自己将如上方法融入到你自己的代码中就行了。 代码实现过滤不雅文字功能,在springboot 里面写一个配置类加上@Configuration注解,在项目启动的时候加载一下,代码如下: package com.***.***.interceptor; import org.springframework.context.annotation.Configuration;import org.springframework.core.io.ClassPathResource;import java.io.*;import java.util.HashMap;import java.util.HashSet;import java.util.Map;import java.util.Set; //屏蔽敏感词初始化@Configuration@SuppressWarnings({ "rawtypes", "unchecked" })public class SensitiveWordInit { // 字符编码 private String ENCODING = "UTF-8"; // 初始化敏感字库 public Map initKeyWord() throws IOException { // 读取敏感词库 ,存入Set中 Set wordSet = readSensitiveWordFile(); // 将敏感词库加入到HashMap中//确定有穷自动机DFA return addSensitiveWordToHashMap(wordSet); } // 读取敏感词库 ,存入HashMap中 private Set readSensitiveWordFile() throws IOException { Set wordSet = null; ClassPathResource classPathResource = new ClassPathResource("static/censorword.txt"); InputStream inputStream = classPathResource.getInputStream(); //敏感词库 try { // 读取文件输入流 InputStreamReader read = new InputStreamReader(inputStream, ENCODING); // 文件是否是文件 和 是否存在 wordSet = new HashSet(); // StringBuffer sb = new StringBuffer(); // BufferedReader是包装类,先把字符读到缓存里,到缓存满了,再读入内存,提高了读的效率。 BufferedReader br = new BufferedReader(read); String txt = null; // 读取文件,将文件内容放入到set中 while ((txt = br.readLine()) != null) { wordSet.add(txt); } br.close(); // 关闭文件流 read.close(); } catch (Exception e) { e.printStackTrace(); } return wordSet; } // 将HashSet中的敏感词,存入HashMap中 private Map addSensitiveWordToHashMap(Set wordSet) { // 初始化敏感词容器,减少扩容操作 Map wordMap = new HashMap(wordSet.size()); for (String word : wordSet) { Map nowMap = wordMap; for (int i = 0; i < word.length(); i++) { // 转换成char型 char keyChar = word.charAt(i); // 获取 Object tempMap = nowMap.get(keyChar); // 如果存在该key,直接赋值 if (tempMap != null) { nowMap = (Map) tempMap; } // 不存在则,则构建一个map,同时将isEnd设置为0,因为他不是最后一个 else { // 设置标志位 Map newMap = new HashMap(); newMap.put("isEnd", "0"); // 添加到集合 nowMap.put(keyChar, newMap); nowMap = newMap; } // 最后一个 if (i == word.length() - 1) { nowMap.put("isEnd", "1"); } } } return wordMap; }} 然后这是工具类代码 : package com.***.***.interceptor; import java.io.IOException;import java.util.HashSet;import java.util.Iterator;import java.util.Map;import java.util.Set; //敏感词过滤器:利用DFA算法 进行敏感词过滤public class SensitiveFilter { //敏感词过滤器:利用DFA算法 进行敏感词过滤 private Map sensitiveWordMap = null; // 最小匹配规则 public static int minMatchType = 1; // 最大匹配规则 public static int maxMatchType = 2; // 单例 private static SensitiveFilter instance = null; // 构造函数,初始化敏感词库 private SensitiveFilter() throws IOException { sensitiveWordMap = new SensitiveWordInit().initKeyWord(); } // 获取单例 public static SensitiveFilter getInstance() throws IOException { if (null == instance) { instance = new SensitiveFilter(); } return instance; } // 获取文字中的敏感词 public Set getSensitiveWord(String txt, int matchType) { Set sensitiveWordList = new HashSet(); for (int i = 0; i < txt.length(); i++) { // 判断是否包含敏感字符 int length = CheckSensitiveWord(txt, i, matchType); // 存在,加入list中 if (length >0) {sensitiveWordList.add (txt.substring (I, I + length)); / / minus 1 because for increases I = I + length-1;}} return sensitiveWordList } / / replace sensitive word characters public String replaceSensitiveWord (String txt, int matchType, String replaceChar) {String resultTxt = txt; / / get all sensitive words Set set = getSensitiveWord (txt, matchType); Iterator iterator = set.iterator (); String word = null; String replaceString = null While (iterator.hasNext ()) {word = iterator.next (); replaceString = getReplaceChars (replaceChar, word.length ()); resultTxt = resultTxt.replaceAll (word, replaceString);} return resultTxt } / * get the replacement string * * @ param replaceChar * @ param length * @ return * / private String getReplaceChars (String replaceChar, int length) {String resultReplace = replaceChar; for (int I = 1; I
< length; i++) { resultReplace += replaceChar; } return resultReplace; } /** * 检查文字中是否包含敏感字符,检查规则如下: * 如果存在,则返回敏感词字符的长度,不存在返回0 * @param txt * @param beginIndex * @param matchType * @return */ public int CheckSensitiveWord(String txt, int beginIndex, int matchType) { // 敏感词结束标识位:用于敏感词只有1位的情况 boolean flag = false; // 匹配标识数默认为0 int matchFlag = 0; Map nowMap = sensitiveWordMap; for (int i = beginIndex; i < txt.length(); i++) { char word = txt.charAt(i); // 获取指定key nowMap = (Map) nowMap.get(word); // 存在,则判断是否为最后一个 if (nowMap != null) { // 找到相应key,匹配标识+1 matchFlag++; // 如果为最后一个匹配规则,结束循环,返回匹配标识数 if ("1".equals(nowMap.get("isEnd"))) { // 结束标志位为true flag = true; // 最小规则,直接返回,最大规则还需继续查找 if (SensitiveFilter.minMatchType == matchType) { break; } } } // 不存在,直接返回 else { break; } } if (SensitiveFilter.maxMatchType == matchType){ if(matchFlag < 2 || !flag){ //长度必须大于等于1,为词 matchFlag = 0; } } if (SensitiveFilter.minMatchType == matchType){ if(matchFlag < 2 && !flag){ //长度必须大于等于1,为词 matchFlag = 0; } } return matchFlag; }} 在你代码的controller层直接调用方法判断即可: //非法敏感词汇判断 SensitiveFilter filter = SensitiveFilter.getInstance(); int n = filter.CheckSensitiveWord(searchkey,0,1); if(n >0) {/ / there is an illegal character logger.info ("this person typed an illegal character-- > {}, I don't know what he is looking for ~ userid-- > {}", searchkey,userid); return null;}
Sensitive text can also be replaced with characters such as *:
SensitiveFilter filter = SensitiveFilter.getInstance (); String text = "sensitive text"; String x = filter.replaceSensitiveWord (text, 1, "*")
Finally, the SensitiveWordInit.java just used the censorword.text file, put your project inside the resources directory under the static directory, this file is the indecent text Daquan, but also need you to update with the times, the project will be loaded when the start of the file.
At this point, the study on "how to use java and redis to achieve a simple hot search function" is over. I hope to be able to solve your doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.