Nachdem ich diese Methode geübt habe, kombiniert mit den Meinungen der Senioren im vorherigen Artikel, bin ich der Meinung, dass dies die einzige Methode ist, die praktikabler und konsistenter ist Eigenschaften von Redis. Letztendlich ist es jedoch immer noch nicht so effizient wie Speicher.
Detaillierte Implementierungsideen finden Sie im Blog des Redis-Autors (Referenz 1). Das Beispiel hier basiert immer noch auf Benutzername und führt nur eine Wortsegmentierung mit einer Länge von 3 für Phrasen durch Erweitern Sie es selbst für andere Szenarien.
Zuerst müssen wir basierend auf der AutoComplete-Buchstabensuche eine Wortsegmentierung für alle Namen durchführen, das heißt:
abc => #🎜🎜 #
Wenn wir a eingeben, erhalten wir direkt den Inhalt der Menge a; wenn wir ab eingeben, erhalten wir direkt den Inhalt der Menge ab. Dann beginnen wir mit der Konvertierung. Zuerst müssen wir die Namen der Benutzertabelle segmentieren:var redis = ConnectionMultiplexer.Connect("localhost");var db = redis.GetDatabase();for (var i = 1; i < 4; i++) { var data = dbCon.Lookup<string, int>(string.Format(@"select words, id from ( select Row_number() over (partition by words order by name) as rn,id,words from ( select id, SUBSTRING(name, 1, {0}) as words, name from User ) as t ) t2 where rn <= {1} and words != '' and words is not null", i, 20)); data.ForEach((key, item) => { db.SetAdd("capqueen:Cache:user:" + key.ToLower(), item.Select<int, RedisValue>(j => j).ToArray()); }); }Schritt 1: Verwenden Sie SQL, um die ersten 20 Daten für jedes Segment zu sortieren und herauszufiltern hier. Syntax. Teil 2: In RedisSet speichern. Dies ist nur ein Index und speichert nicht den spezifischen Benutzerinhalt. Bei der Suche können wir Folgendes implementieren:# 🎜🎜 #
public List<User> SearchWords(string keywords) { var redis = ConnectionMultiplexer.Connect("localhost"); var db = redis.GetDatabase(); var result = db.SetMembers("capqueen:Cache:user:" + keywords.ToLower()); var users = new List<User>(); if (result.Any()) { //转换成ids var ids = result.ToList().Select<RedisValue, RedisKey>(i => i.ToString()); //按照keys获取value ,事先已经存好了Usersvar values = db.StringGet(ids.ToArray()); //构造List Json以加速解析var portsJson = new StringBuilder("["); values.ToList().ForEach(item =>{ if (!string.IsNullOrWhiteSpace(item)) { portsJson.Append(item).Append(","); } }); portsJson.Append("]"); users = JsonConvert.DeserializeObject<List<User>>(portsJson.ToString()); } }
Nach tatsächlichen Tests ist diese Schreibmethode zwar viel besser als die vorherigen Schlüssel, aber die Leistung ist immer noch unbefriedigend.
Scan-Suchmethode
Je nach unterschiedlicher Datenstruktur ist Scan in SCAN, HSCAN, SSCAN und ZSCAN unterteilt. Weitere Einzelheiten finden Sie in der Dokumentation. Wir verwenden hier ZSCAN:
ZSCAN-Tastencursor [MATCH-Muster] [COUNT-Anzahl]
Hier ist der Cursor ein Cursor für die Suchiteration. Ich habe die Details nicht herausgefunden noch, Muster Die übereinstimmende Regelanzahl ist die Anzahl der Datensätze
Da ich StackExchange.Redis verwende, lautet die bereitgestellte Zscan-Methode:
IEnumerable SortedSetScan(RedisKey key, RedisValue pattern = null , int pageSize = 10, longcursor = 0, int pageOffset = 0, CommandFlags flags = CommandFlags.None);
public void CreateTerminalCache(List<User> users) { if (users == null) return; var db = ConnectionMultiplexer.GetDatabase(); var sourceData = new List<KeyValuePair<RedisKey, RedisValue>>(); //构造集合数据var list = users.Select(item =>{ var value = JsonConvert.SerializeObject(item); //构造原始数据sourceData.Add(new KeyValuePair<RedisKey, RedisValue>("capqueen:users:" + item.Id, value)); //构造数据 return new SortedSetEntry(item.Name, item.Id); }); //添加进有序集合,采用name - id db.SortedSetAdd("capqueen:users:index", list.ToArray()); //添加港口数据key-value db.StringSet(sourceData.ToArray(), When.Always, CommandFlags.None); }
Dann lautet die Suche wie folgt:
public List<User> GetUserByWord(string words) { var db = ConnectionMultiplexer.GetDatabase(); //搜索var result = db.SortedSetScan("capqueen:users:index", words + "*", 10, 1, 30, CommandFlags.None).Take(30).ToList(); var users = new List<User>(); if (result.Any()) { //转换成ids var ids = result.ToList().Select<SortedSetEntry, RedisKey>(i => i.ToString()); //按照keys获取valuevar values = db.StringGet(ids.ToArray()); //构造List Json以加速解析var portsJson = new StringBuilder("["); values.ToList().ForEach(item =>{ if (!string.IsNullOrWhiteSpace(item)) { portsJson.Append(item).Append(","); } }); portsJson.Append("]"); users = JsonConvert.DeserializeObject<List<User>>(portsJson.ToString()); } return users; }
Das obige ist der detaillierte Inhalt vonSo verwenden Sie die Wortsegmentierungsindexmethode von Redis. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!