redisファジイ検索

10614 ワード


 
【redisファジイ検索】
テキストリンク:https://www.cnblogs.com/commissar-Xia/p/7759484.html
最近Redisを使ってプロジェクトの机能を最适化して、その中の一部はあいまいな検索で、多くの招待状を探して、同じくとても良い解决策と考えを探し当てていないで、最后に皇天は心を负わないで、ついに私に探し当てさせました!!!
作者:WalkerAlone原文リンク:http://blog.csdn.net/qq_28893679/article/details/53005057
Redisのkeysコマンドでkey値を取得できます.具体的なコマンドフォーマットはkeys patternです.
ここでredisであいまいなクエリを許可するワイルドカードは、*、?の3つです.[]
次のようになります.
*:任意の複数文字を使用可能
?:共通文字
[]:カッコ内の文字を1文字配置する
=========================================================================
実際のプロジェクトではspring統合redisのRedisTemplateを使用して操作する可能性があります.これにより、keysメソッドがStringRedisTemplateサブクラス(親-RedisTemplate)に存在するため、テンプレートの注入時にファジイクエリが使用できなくなる可能性があります.
スプリング構成では、必ず注意!!!
=========================================================================
実際の操作における具体的な考え方:
1.クエリーする条件をキーとしてZSetストレージを行う
2.取得時にStringRedisTemplateを呼び出す.keys(pattern)、例:
1 2 3 4 5 public   Set keys(String pattern){    return   stringRedisTemplate.keys( "*"   + pattern +  "*" );     // return stringRedisTemplate.keys("?" + pattern);    // return stringRedisTemplate.keys("[" + pattern + "]"); }
 
ps:ファジイ検索はStringデータ構造に適用され、redisでサポートされている他の構造(List、setなど)に対して、サポートされているかどうかは検証されていません.
 
実践コード:
/**
 * redis     
 */
@Service
public class RedisCacheService implements InitializingBean {

	private ValueOperations valueOperations;

	@Autowired
	private StringRedisTemplate redisTemplate;

	@SuppressWarnings("unchecked")
	@Override
	public void afterPropertiesSet() throws Exception {
		RedisSerializer redisSerializer = new StringRedisSerializer();
		valueOperations = redisTemplate.opsForValue();
	}

	/**
	 *           
	 * @param key
	 * @return
	 */
	public List getCacheResource(String key) {
		Set keys = redisTemplate.keys(key);
		if (CollectionUtils.isEmpty(keys)) {
			return new ArrayList<>();
		}

		List resourceCacheBOList = new ArrayList<>();
		for (String accurateKey : keys) {
			String cacheValue = valueOperations.get(accurateKey);
			List sub = JSONArray.parseArray(cacheValue, ResourceCacheBO.class);
			resourceCacheBOList.addAll(sub);
		}

		return resourceCacheBOList;
	}


 
【keyは存在するが、redisTemplateは見つからない】
質問:key:[A_091_JPFX]が存在しますが、あいまいkey:[A_*_JPFX]で一致した場合、一致しません.エンコードの問題という資料がありますが、次のように解決します.
原文リンク:redisTemplate.keys(pattern)ファジイクエリでkeysが見つかりません:https://blog.csdn.net/cutterwolf/article/details/77990112
 
redisTemplateを使用しています.keysがkeysを検索すると、対応するkeyが存在するのに、あいまいなクエリーは検索できないことに気づいた.原因は二つある.クエリー文字列が正しいかどうかを確認します.はい、あなたのkey値は文字化けしている可能性があります.つまり、xcaxedにあなたのkeyなどの文字化けしていることに遭遇しました.たとえば、keyを再定義する必要がある画像の説明を書きます.
 @Bean  
    public RedisTemplate redisTemplate(RedisConnectionFactory factory) {  
       RedisTemplate redisTemplate = new RedisTemplate();  
       redisTemplate.setConnectionFactory(factory);  

       //key     ;(       ;),        Long  String    ,        ;  
       //         key       ,             ,           ObjectRedisSerializer  
       //  JdkSerializationRedisSerializer     ;  
     RedisSerializer redisSerializer = new StringRedisSerializer();//Long            ;  
     redisTemplate.setKeySerializer(redisSerializer);  
     redisTemplate.setHashKeySerializer(redisSerializer);  

       return redisTemplate;  
    }   

 
 
完全なコード:
package cn.xxt.word.analysis.service;

import cn.xxt.ssm.commons.exception.BizException;
import cn.xxt.ssm.commons.json.JacksonJsonUtil;
import cn.xxt.word.analysis.pojo.bo.QuestCacheBO;
import cn.xxt.word.analysis.pojo.bo.ResourceCacheBO;
import com.alibaba.fastjson.JSONArray;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;

/**
 * redis     
 */
@Service
public class RedisCacheService implements InitializingBean {

	private ValueOperations valueOperations;

	@Autowired
	private StringRedisTemplate redisTemplate;

	@SuppressWarnings("unchecked")
	@Override
	public void afterPropertiesSet() throws Exception {
		RedisSerializer redisSerializer = new StringRedisSerializer();//Long            ;
		redisTemplate.setKeySerializer(redisSerializer);
		redisTemplate.setHashKeySerializer(redisSerializer);
		valueOperations = redisTemplate.opsForValue();
	}

	/**
	 *     
	 * @param key
	 * @param resourceCacheBOList
	 */
	public void cacheResource(String key, List resourceCacheBOList) {
		//     
		if (CollectionUtils.isEmpty(resourceCacheBOList)) {
			throw new BizException(1, "    ");
		}
		//   
		String resourceCacheValue = JacksonJsonUtil.objectToString(resourceCacheBOList);
		valueOperations.set(key, resourceCacheValue);
	}

	/**
	 *           
	 * @param key
	 * @return
	 */
	// TODO    
	public List getCacheResource(String key) {
		Set keys = redisTemplate.keys(key);
		if (CollectionUtils.isEmpty(keys)) {
			return new ArrayList<>();
		}

		List resourceCacheBOList = new ArrayList<>();
		for (String accurateKey : keys) {
			String cacheValue = valueOperations.get(accurateKey);
			List sub = JSONArray.parseArray(cacheValue, ResourceCacheBO.class);
			resourceCacheBOList.addAll(sub);
		}

		return resourceCacheBOList;
	}

	/**
	 *          
	 * @param key
	 * @return
	 */
	public void cacheKeyWordCode(String key, String code) {
		//     
		if (StringUtils.isEmpty(key) || StringUtils.isEmpty(code)) {
			throw new BizException(1, "    ");
		}
		//   
		valueOperations.set(key, code);
	}

	/**
	 *          
	 * @param key
	 * @return
	 */
	public String getKeyWordCode(String key) {
		String keyWordCode = valueOperations.get(key);
		if (StringUtils.isEmpty(keyWordCode)) {
			return null;
		} else {
			return keyWordCode;
		}
	}

	/**
	 *            
	 * @param keys
	 * @return
	 */
	public List batchGetKeyWordCode(List keys) {
		List codes = valueOperations.multiGet(keys);
		if (CollectionUtils.isEmpty(codes)) {
			return new ArrayList<>();
		} else {
			codes.removeAll(Collections.singleton(null));
			return codes;
		}
	}

}

 
【RedisTemplateとStringRedisTemplateの違い】
テキストリンク:https://blog.csdn.net/notsaltedfish/article/details/75948281
 
最近はRedisの勉強やJavaでのRedisの使い方を始めていますが、Redisが何なのかはここでは言いません.
私が主に言いたいのは、RedisとJavaのSpringが結合したときに使うRedisTemplateとStringRedisTemplateです
彼らの両者の違いと、どのように使うべきか.
RedisTemplateはこのクラスの名前の接尾辞がTemplateであることを見て、Springがどのように関係型データベースに接続するかを知っていれば、このクラスが何をしているのか推測するのは難しくありません.JdbcTemplateと同じようにRedisに対するよく使われる操作をパッケージ化しています.もちろんStringRedisTemplateはRedisTemplateと似ています.では、なぜ2つのTemplateが必要なのかと聞かれるに違いありません.一つで十分じゃないですか.実は彼らの両者の違いは主に彼らが使っているシーケンス化クラスにある.
  • RedisTemplateはJdkSerializationRedisSerializer
  • を使用しています
  • StringRedisTemplateは、StringRedisSerializer
  • を使用しています.
     
    RedisTemplateで使用されるシーケンスクラスは、データを操作するとき、例えばデータを格納すると、データがバイト配列にシーケンス化されます.
    そしてRedisデータベースに格納し、この時点でRedisを開いて表示すると、あなたのデータが読み取り可能な形式ではないことがわかります.
    以下のようにバイト配列で表示されます
    もちろんRedisからデータを取得する場合も、デフォルトではバイト配列としてデータが変換されます.
    データがバイト配列でredisに存在するのではなく、通常の読み取り可能な文字列である場合、例えば次のような形式のデータ

    注意:使用するソフトウェアはRedisDesktopManagerです
    RedisTemplateではパイロットデータを取得できません.このとき取得した値はNULLです.この時StringRedisTempateが役に立ちました
     
    Redisのデータ値が読み取り可能な形で表示されている場合は、StringRedisTemplateを使用して中のデータを取得するしかありません.
    RedisTemplateを使用してデータが取得できない場合は、Redisのデータがバイト配列ではなく読み取り可能な形式であるかどうかを確認してください.
     
    また私はテスト時にStringRedisTemplateのシーケンス化クラスをRedisTemplateのJ d k SerializationRedisSerializerに変更しても
    最後にシーケンス化されたオブジェクトデータは取得できません.オブジェクトに変換されていないバイト配列でも、コードは次のようになります.
    @Test
    
    public void testRedisSerializer(){
    
    User u = new User();
    
    u.setName("java");
    
    u.setSex("male");
    
    redisTemplate.opsForHash().put("user:","1",u);
    
    /*  redisTemplate  Serializer*/
    
    System.out.println(redisTemplate.getKeySerializer());
    
    System.out.println(redisTemplate.getValueSerializer());
    
    
    /*  StringRedisTemplate  Serializer*/
    
    System.out.println(stringRedisTemplate.getValueSerializer());
    
    System.out.println(stringRedisTemplate.getValueSerializer());
    
    
    /* stringRedisTemplate       RedisTemplate     */
    
    stringRedisTemplate.setKeySerializer(new JdkSerializationRedisSerializer());
    
    stringRedisTemplate.setValueSerializer(new JdkSerializationRedisSerializer());
    
    
    /*     stringRedisTemplate  Serializer redisTemplate   
    
    * JdkSerializationRedisSerializer
    
    *        redis         
    
    * */
    
    System.out.println(stringRedisTemplate.getValueSerializer());
    
    System.out.println(stringRedisTemplate.getValueSerializer());
    
    
    User user = (User) redisTemplate.opsForHash().get("user:","1");
    
    User user2 = (User) stringRedisTemplate.opsForHash().get("user:","1");
    
    System.out.println("dsd");
    
    }


    まとめ:
    Redisデータベースに文字列データが保存されているか、アクセスするデータが文字列タイプデータである場合は、StringRedisTemplateを使用します.
    しかし、データが複雑なオブジェクトタイプで、取り出すときにデータ変換をしたくない場合は、Redisから直接オブジェクトを取り出すと、RedisTemplateを使用するのがより良い選択です.