redis的索引模式

redis的索引模式基本是基于sorted set的,因sorted set有数值,数值就是索引,你可以根据它找到其他值。

sorted set

sorted set是set和hash的混合结构。

它不能重复,这点像set。

它里面的每个元素都和一个浮点数映射(对应),这点像hash。

举例:


按照生年排序(全部)。


找到1950年前生的黑客。


删除1940年到1960年出生的黑客。

更多操作可以查询help @sorted_set

sorted set的内部结构是跳跃表。跳跃表是一种链表,它的查询时间复杂度是 O ( log ⁡ 2 n ) O(\log_2 n) O(log2n)


字典排序

如果score相等,那么就会按照字母的字典顺序来排序:

我们可以找出一定字母范围内的黑客:


这里的A和P是包含进来的。

这里的lexLexicographical 的意思,就是字典。

如果你想得到以某个字母开始的所有黑客,可以这么写:


只要前两个的话加上分页:

地理信息

redis有经纬度的指令,很神奇。


我们有一个cars的集合,里面的一个成员是my-car,经纬度由一对数值给定。

关键是,怎么这些数就是经纬度了呢?

redis用geohash把这些数转换成sorted set的score。因此地理信息功能还是基于sorted set的。

更新经纬度:



再来一辆车:


两辆车的距离:


这是以米为单位的。


以英尺为单位。


以某个点为圆心,半径100m以内的所有车子。


以robins-car为圆心,半径152m以内的所有车辆。


带上距离和坐标。


删除一辆车。

文本查询

redis有文本搜索的功能,我们将用set简单地实现一下,当然你也可以用sorted set,只要再携带score就行了。

比如我这里有三句话:

“Redis is very fast”

“Cheetahs are fast”

“Cheetahs have spots”

我们用set将它们分别存起来:


这告诉我们的是:哪一个文档有哪些词。

然后,反转:


这告诉我们:一个词在哪一个文档。


有very并且有fast的文档是:ex1、ex2。


有cheetahs或者有redis的文档是:ex1、ex2、ex3。

要删除一个文档,首先要找出它的所有单词,然后删除以该单词为索引的文档:

redis search

文本搜索redis有专门的模块。

下载使用:

git clone --recursive https://github.com/RediSearch/RediSearch.git
make build
make run


运行之后,我们可以看到,name是full text,版本是一堆9。


解释一下:
myIdx是key。
SCHEMA表示后面跟的东西是搜索索引的字段。
后面的title Text等等的都是字段+类型的模式。

添加文档:


我们往myIdx上加一个文档doc1,ID是1.0

FIELDS表示后面都是为字段赋值的。


我们探究一下这个奇怪的数据结构:


redis本身不认识我们创建的index。


一共有10个key。


ft_index0是RediSearch自己的数据类型。


doc1是用hash来存储的。


ft_invidx表示http是一个文本索引。


搜索:


有“hello world”的文档就我们刚建的一个。


自动补全:


我们在autocomplete这个字典中增加了一个suggestion,后面的100是“hello world”的权重。


jredisearch

java也有操作redisearch的库。

pom:

<dependency>
		<groupId>com.redislabs</groupId>
		<artifactId>jredisearch</artifactId>
		<version>0.21.0</version>
	</dependency>

	<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
	<dependency>
		<groupId>redis.clients</groupId>
		<artifactId>jedis</artifactId>
		<version>2.9.1</version>
	</dependency>

github给出的版本太高了,会报依赖冲突的错。

在server端启动redis server:

./redis-server /home/ocean/redis-5.0.7/redis.conf --loadmodule /home/ocean/redis_search/RediSearch/src/redisearch.so timeout 100



我带上了redis.confredisearch.so


public class Redissearch {
	public static void main(String[] args) {
		//create a redis client
		Client client = new Client("myIdx", "192.168.8.125", 6379,10000,10);

		//create a schema
		Schema sc = new Schema()
				.addTextField("title", 5.0)
				.addTextField("body", 1.0)
				.addNumericField("price");

		//create the index
		client.createIndex(sc, Client.IndexOptions.Default());

		//set the fields
		Map<String, Object> fields = new HashMap<>();
		fields.put("title", "hello world");
		fields.put("state", "NY");
		fields.put("body", "lorem ipsum");
		fields.put("price", 1337);

		//create a doc
		client.addDocument("doc1", fields);

		// Creating a complex query
		Query q = new Query("hello world")
				.addFilter(new Query.NumericFilter("price", 0, 2000))
				.limit(0,5);

		// actual search
		SearchResult res = client.search(q);

		List<Document> docs = res.docs;
		docs.stream().forEach(System.out::println);
	}
}




代码的语义很好懂。我们要查询有hello world的文档并且价格在0到2000之间。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Redis 提供了多种数据结构,其中一些支持高效的索引和查找操作。对于键值对存储的 Redis 数据库来说,索引主要体现在以下数据结构中: 1. **哈希表(Hash)**:Redis 的哈希类型(`HASH`或`HSET`)可以用字段名作为索引。通过给定的哈希字段,可以直接访问或修改对应的值,类似于字典的数据结构。 2. **有序集合(Sorted Set)**:在有序集合中,每个元素都有一个分数(score),可以使用分数作为索引进行范围查询,如`ZRANGE`命令可以返回指定分数范围内的元素。另外,也可以使用成员的排名(rank)作为索引。 3. **列表(List)**:列表虽然不是严格意义上的索引结构,但可以通过索引(从头开始计数)访问元素,`LINDEX`命令可以用于此目的。不过,如果需要高效地按值查找元素,一般会配合其他数据结构。 4. **集合(Set)**:集合中的元素没有顺序,也不支持基于元素值的索引,但可以通过集合的操作(如`SISMEMBER`)查找元素是否存在。 5. **字符串(String)**:对于简单的字符串键,它们本身并不支持索引,但可以通过哈希或有序集合的底层数据结构间接实现查找功能。 每种数据结构的索引机制和效率各不相同,选择哪种数据结构取决于具体的应用场景和需求。Redis 索引的设计旨在提供快速的查询性能,但通常不会像 SQL 数据库那样提供复杂的全文索引或复合索引。如果你需要更详细的索引策略,可以根据应用的具体查询模式进行优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值