Author: Shannon’s private kitchen

Blog.csdn.net/qq_25838777…

Use Java and Redis to implement a simple heat search function, with the following functions:

1: The search bar displays the search history of the current logged-in individual user and deletes the personal history record

2: the user input a character in the search bar, the character will be recorded in redis stored in Zset format, record the number of the character is searched and the current timestamp (with the DFA algorithm, interested in their own Baidu learn it)

3: Whenever the user queries the characters that already exist in Redis, the number will be directly added up to obtain the ten hottest data queried on the platform. (You can either write your own interface or add some prepared keywords directly to Redis)

4: Finally do indecent text filtering function. This is important. You know what I mean.

Code to achieve hot search and personal search record function, the main controller layer under several methods:

1: add hot search terms to Redis (use the following indecent word filtering method to filter this term when adding, and then save it legally

2: Give the related word +1 heat per click

3: Search the top 10 hottest by key

4: Insert personal search history

5: Query personal search history


First, configure the redis data source and other basic (not familiar with my other blog, Redis multi-metadata configuration).

Finally, paste the code for 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 {// Implements redisService @Resource(name = "redisSearchTemplate") private StringRedisTemplate redisSearchTemplate; @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; } @override public Long delSearchHistoryByUserId(String userid, String searchkey) { String shistory = RedisKeyUtils.getSearchHistoryKey(userid); return redisSearchTemplate.opsForHash().delete(shistory, searchkey); @override public List<String> getSearchHistoryByUserId(String userId) {List<String> stringList = null; String shistory = RedisKeyUtils.getSearchHistoryKey(userid); boolean b = redisSearchTemplate.hasKey(shistory); if(b){ Cursor<Map.Entry<Object, Object>> cursor = redisSearchTemplate.opsForHash().scan(shistory, ScanOptions.NONE); while (cursor.hasNext()) { Map.Entry<Object, Object> map = cursor.next(); String key = map.getKey().toString(); stringList.add(key); } return stringList; } return null; } // Add a hot word search record, @override public int incrementScoreByUserId(String searchKey) {Long now = system.currentTimemillis (); ZSetOperations zSetOperations = redisSearchTemplate.opsForZSet(); ValueOperations<String, String> valueOperations = redisSearchTemplate.opsForValue(); List<String> 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) <= 0) { zSetOperations.add("title", tle, 0); valueOperations.set(tle, String.valueOf(now)); } } catch (Exception e) { zSetOperations.add("title", tle, 0); valueOperations.set(tle, String.valueOf(now)); } } return 1; } // Search for the top ten hottest names based on searchkey (if searchkey is null, @override public List<String> getHotList(String searchkey) {String key = searchkey; Long now = System.currentTimeMillis(); List<String> result = new ArrayList<>(); ZSetOperations zSetOperations = redisSearchTemplate.opsForZSet(); ValueOperations<String, String> valueOperations = redisSearchTemplate.opsForValue(); Set<String> value = zSetOperations.reverseRangeByScore("title", 0, Double.MAX_VALUE); If (stringutils.isnotempty (searchKey)){for (String val: Value) {if (StringUtils. ContainsIgnoreCase (val, key)) {if (result. The size () > 9) {/ / return only one of the top 10 hottest break; } Long time = Long.valueOf(valueOperations.get(val)); If ((now-time) < 2592000000L) {// Return the last month's data result.add(val); } else {zsetoperations. add("title", val, 0); }}}}else{for (String val: value) {if (result.size() > 9) {// only return the hottest top ten break; } Long time = Long.valueOf(valueOperations.get(val)); If ((now-time) < 2592000000L) {// Return the last month's data result.add(val); } else {zsetoperations. add("title", val, 0); } } } return result; Override public int incrementScore(String key) {String key = searchkey; Long now = System.currentTimeMillis(); ZSetOperations zSetOperations = redisSearchTemplate.opsForZSet(); ValueOperations<String, String> valueOperations = redisSearchTemplate.opsForValue(); zSetOperations.incrementScore("title", key, 1); valueOperations.getAndSet(key, String.valueOf(now)); return 1; }}Copy the code

The core is done, and the rest is up to you to incorporate the above methods into your own code.


** Code to filter inoffensive text function, in springBoot to write a Configuration class with @Configuration annotation, when the project is loaded, the code is as follows ** :

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 {// Reads the sensitive theskeyword and stores it in Set Set<String> wordSet = readSensitiveWordFile(); / / add the sensitive word library to HashMap / / determine the DFA finite automaton return addSensitiveWordToHashMap (wordSet); Private Set<String> readSensitiveWordFile() throws IOException {Set<String> wordSet = null; ClassPathResource classPathResource = new ClassPathResource("static/censorword.txt"); InputStream inputStream = classPathResource.getInputStream(); InputStreamReader read = new InputStreamReader(inputStream, ENCODING); WordSet = new HashSet<String>(); // StringBuffer sb = new StringBuffer(); // BufferedReader is a wrapper class that reads characters into the buffer until the buffer is full. BufferedReader br = new BufferedReader(read); String txt = null; While ((TXT = br.readline ())! = null) { wordSet.add(txt); } br.close(); // Close the file stream read.close(); } catch (Exception e) { e.printStackTrace(); } return wordSet; } / / words from the HashSet, deposited in the HashMap private Map addSensitiveWordToHashMap (Set < String > wordSet) {/ / initializes the sensitive word container, WordMap = new HashMap(wordset.size ()); for (String word : wordSet) { Map nowMap = wordMap; for (int i = 0; i < word.length(); KeyChar = word.charat (I); // Get Object tempMap = nowmap. get(keyChar); // If the key exists, specify if (tempMap! = null) { nowMap = (Map) tempMap; Else {// Set the flag bit map <String, String> newMap = new HashMap<String, String>(); newMap.put("isEnd", "0"); // Add to the collection nowmap. put(keyChar, newMap); nowMap = newMap; } / / the last an if (I = = word. The length () - 1) {nowMap. Put (" isEnd ", "1"); } } } return wordMap; }}Copy the code

Then here’s the utility class code:

package com.***.***.interceptor; import java.io.IOException; import java.util.HashSet; import java.util.Iterator; import java.util.Map; import java.util.Set; Public class sensitiveWordMap public class sensitiveWordMap public class sensitiveWordMap private Map sensitiveWordMap = null; Public static int minMatchType = 1; Public static int maxMatchType = 2; Private static SensitiveFilter instance = null; Private sensitiveWordMap = new SensitiveWordInit().initkeyword (); private sensitiveWordMap = new SensitiveWordInit().initkeyword ();  } // Obtain singleton public static SensitiveFilter getInstance() throws IOException {if (null == instance) {instance = new SensitiveFilter(); } return instance; } public Set<String> getSensitiveWord(String sensitiveword, int matchType) { Set<String> sensitiveWordList = new HashSet<String>(); for (int i = 0; i < txt.length(); I ++) {int length = CheckSensitiveWord(TXT, I, matchType); If (length > 0) {sensitiveWordlist.add (txt.substring(I, I + length)); // for will increment I = I + length-1; } } return sensitiveWordList; } public String replaceSensitiveWord(String TXT, int matchType, String replaceChar) {String resultTxt = TXT;  Set<String> Set = getSensitiveWord(TXT, matchType); Iterator<String> 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; } /** * Check whether the text contains sensitive characters as follows: <br> * Returns the length of the sensitive word character if it exists, Public int CheckSensitiveWord(String, TXT, CheckSensitiveWord) Int beginIndex, int matchType) {// End identifier of sensitive words: Boolean flag = false; Int matchFlag = 0; Map nowMap = sensitiveWordMap; for (int i = beginIndex; i < txt.length(); i++) { char word = txt.charAt(i); // Get the specified key nowMap = (Map) nowmap. get(word); If (nowMap! = null) {// find the corresponding key, match the flag +1; If ("1".equals(nowmap.get ("isEnd"))) {// The end flag bit is true flag = true; Returned directly, the biggest, / / minimum rules, which still need to continue to find the if (SensitiveFilter. MinMatchType = = matchType) {break; }}} // do not exist, just return else {break; } } if (SensitiveFilter.maxMatchType == matchType){ if(matchFlag < 2 || ! Flag){// The length must be greater than or equal to 1, for the word matchFlag = 0; } } if (SensitiveFilter.minMatchType == matchType){ if(matchFlag < 2 && ! Flag){// The length must be greater than or equal to 1, for the word matchFlag = 0; } } return matchFlag; }}Copy the code

Call methods directly from the Controller layer of your code:

/ / illegal sensitive judgment SensitiveFilter filter = SensitiveFilter. GetInstance (); Int n = filter. CheckSensitiveWord (searchkey, 0, 1); If (n > 0){logger.info(userID --> {}, userId); if(n > 0){logger.info(userID --> {}); return null; }Copy the code

Sensitive text can also be replaced with * and other characters:

SensitiveFilter filter = SensitiveFilter.getInstance(); String text = "sensitive text "; String x = filter.replaceSensitiveWord(text, 1, "*");Copy the code

The sensitiveWordinit.java file contains a static file called Censorword. text. The sensitiveWordinit.java file contains a static file called censorword.text. This file is loaded when the project starts.

Can own Baidu download this thing a lot of. I won’t post the link. If you post the link, it will be disabled and you can’t access it. If you need it, you can leave a message below the article.

If you think the writing is good, hope to give a reward ~~~~~~


Recommend 3 original Springboot +Vue projects, with complete video explanation and documentation and source code:

Build a complete project from Springboot+ ElasticSearch + Canal

  • Video tutorial: www.bilibili.com/video/BV1Jq…
  • A complete development documents: www.zhuawaba.com/post/124
  • Online demos: www.zhuawaba.com/dailyhub

【VueAdmin】 hand to hand teach you to develop SpringBoot+Jwt+Vue back-end separation management system

  • Full 800 – minute video tutorial: www.bilibili.com/video/BV1af…
  • Complete development document front end: www.zhuawaba.com/post/18
  • Full development documentation backend: www.zhuawaba.com/post/19

【VueBlog】 Based on SpringBoot+Vue development of the front and back end separation blog project complete teaching

  • Full 200 – minute video tutorial: www.bilibili.com/video/BV1af…
  • Full development documentation: www.zhuawaba.com/post/17

If you have any questions, please come to my official account [Java Q&A Society] and ask me