Maison  >  Article  >  base de données  >  Comment utiliser la méthode d'index de segmentation de mots Redis

Comment utiliser la méthode d'index de segmentation de mots Redis

王林
王林avant
2023-05-26 17:28:52986parcourir

Méthode d'index de segmentation de mots

Cette méthode est la seule qui, à mon avis, est plus réalisable et plus cohérente avec les caractéristiques de redis après l'avoir pratiquée et combinée avec les avis donnés par mes prédécesseurs dans l'article précédent. Cependant, au final, elle. n'est toujours pas aussi efficace que la mémoire.

Pour des idées de mise en œuvre détaillées, veuillez consulter le blog de l'auteur Redis (référence 1). L'exemple ici est toujours basé sur UserName, en anglais, et effectue uniquement une segmentation de mots d'une longueur de 3 pour les phrases. Veuillez développer vous-même pour d'autres scénarios. .

D'abord en nous basant sur la recherche de lettres de la saisie semi-automatique, nous devons ensuite effectuer une segmentation de mots pour tous les noms, c'est-à-dire :

abc => (a, ab, abc)

Lorsque a est saisi, nous obtiendrons directement l'ensemble a Contenu ; en entrant ab, nous obtiendrons directement le contenu de la collection ab. Ensuite, nous commençons la conversion. Nous devons d'abord segmenter les noms dans la table User :

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 != &#39;&#39; 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());
      });
}

Étape 1 : Utilisez SQL pour trier et filtrer les 20 premiers éléments de données pour chaque segment.

Partie 2 : Enregistrer dans RedisSet. Notez qu'il ne s'agit que d'un index et n'enregistre pas le contenu spécifique de l'utilisateur.

Lors de la recherche, nous pouvons implémenter ce qui suit :

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());
            }
}

Après des tests réels, cette façon d'écrire est meilleure que. le précédent Keys est certes bien meilleur, mais les performances restent insatisfaisantes.

Méthode de recherche par scan

Cette méthode a été découverte par moi après avoir consulté la documentation Redis, mais même s'il s'agit d'un test, on estime qu'elle ne peut pas être utilisée pour des requêtes à grande échelle dans l'environnement de production.

Selon différentes structures de données, Scan est divisé en SCAN, HSCAN, SSCAN et ZSCAN. Voir la documentation pour plus de détails. Nous utilisons ZSCAN ici :

Curseur clé ZSCAN [MATCH pattern] [COUNT count]

Ici, le curseur est un curseur pour l'itération de recherche, je ne l'ai pas encore compris, le motif est la règle de correspondance et le nombre est le nombre de. records

Parce que StackExchange.Redis est utilisé et la méthode zscan qu'il fournit est :

IEnumerable SortedSetScan (clé RedisKey, modèle RedisValue = null, int pageSize = 10, curseur long = 0, int pageOffset = 0, drapeaux CommandFlags = 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);
}

Ensuite, recherchez comme suit :

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;
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer