使用Jedis学习如何在JSON文档中存储、读取和搜索数据
最后更新于 2024年4月26日
目标
Redis可以管理JSON文档,除了索引Redis哈希之外,还可以对JSON文档进行索引和搜索。本文档提供了使用Jedis存储、索引和搜索会话数据的完整示例。
解决方案
本文档详细介绍的示例中,我们将按以下格式存储会话数据
[
{
"lastAccessedTime":1713903362,
"creationTime":1713903362,
"location":"34.638,31.79",
"visited":[
"www.redis.io",
"www.wikipedia.com",
"www.mortensi.com"
],
"cart":[
{
"quantity":1,
"price":1990.99,
"id":"hp-2341"
},
{
"quantity":2,
"price":19.99,
"id":"case-9993"
}
]
}
]
我们还将探索如何创建索引来索引会话的不同部分。让我们开始并按如下方式连接到Redis
HostAndPort node = HostAndPort.from("localhost:6379");
JedisClientConfig clientConfig = DefaultJedisClientConfig.builder()
.resp3()
.build();
UnifiedJedis client = new UnifiedJedis(node, clientConfig);
学习如何使用Jedis设置Maven项目
我们正在创建一个索引;让我们删除可能存在的索引以及所有相关文档。
client.ftDropIndexDD("session_idx");
如果您想保留数据并仅删除索引,请使用命令
ftDropIndex
现在,我们可以通过选择需要索引的字段来定义索引。
Schema schema = new Schema()
.addGeoField("$.location").as("location")
.addTagField("$.cart[*].id").as("item_id")
.addNumericField("$.cart[*].price").as("price")
.addTagField("$.visited[*]").as("visited")
.addNumericField("$.lastAccessedTime").as("updated")
.addNumericField("$.creationTime").as("created");
// Defining the index, it could be HASH too
IndexDefinition def = new IndexDefinition(Type.JSON).setPrefixes(new String[] {"session:"});
// Creating the index
client.ftCreate("session_idx", IndexOptions.defaultOptions().setDefinition(def), schema);
现在,让我们引入一些元数据,如会话创建和更新时间戳,以及表示为经纬度对的用户位置。了解更多关于Redis中的索引信息。
JSONObject jsonObject = new JSONObject();
jsonObject.put("lastAccessedTime", System.currentTimeMillis() / 1000L);
jsonObject.put("creationTime", System.currentTimeMillis() / 1000L);
jsonObject.put("location", "34.638,31.79");
client.jsonSet("session:1", jsonObject);
我们还可以存储一个访问过的URL数组
client.jsonSet("session:1", new Path2("visited"), new ArrayList<>());
List<String> visited = new ArrayList<String>();
visited.add("www.redis.io");
visited.add("www.wikipedia.com");
visited.add("www.mortensi.com");
client.jsonSetWithEscape("session:1", new Path2("visited"), visited);
现在,我们为该用户存储一个包含几个商品的购物车。
// Shopping cart item
JSONObject laptop = new JSONObject();
laptop.put("id", "hp-2341");
laptop.put("price", 1990.99);
laptop.put("quantity", 1);
// Another shopping cart item
JSONObject laptopCase = new JSONObject();
laptopCase.put("id", "case-9993");
laptopCase.put("price", 19.99);
laptopCase.put("quantity", 2);
// Storing items in the shopping cart
client.jsonSet("session:1", new Path2("cart"), new ArrayList<>());
client.jsonArrAppend("session:1", new Path2("cart"), laptop);
client.jsonArrAppend("session:1", new Path2("cart"), laptopCase);
让我们创建第二个会话,以演示如何执行跨会话搜索操作。
// Creating another session
JSONObject jsonObject2 = new JSONObject();
jsonObject2.put("lastAccessedTime", System.currentTimeMillis() / 1000L);
jsonObject2.put("creationTime", System.currentTimeMillis() / 1000L);
jsonObject2.put("location", "34.638,31.79");
client.jsonSet("session:2", jsonObject2);
// Shopping cart item
JSONObject book = new JSONObject();
book.put("id", "sking-2435");
book.put("price", 14.90);
book.put("quantity", 1);
client.jsonSet("session:2", new Path2("cart"), new ArrayList<>());
client.jsonArrAppend("session:2", new Path2("cart"), book);
是时候检索我们的数据了。在屏幕上打印整个会话
System.out.println(client.jsonGet("session:1"));
读取会话的一部分,在此示例中仅读取购物车
System.out.println(client.jsonGet("session:1", new Path2("$.cart")));
您还可以在会话中按ID搜索特定商品并返回价格。搜索语法遵循JSONPath语法。
System.out.println(client.jsonGet("session:1", new Path2("$.cart[?(@.id==\"hp-2341\")].price")));
最后,让我们使用已创建的session_idx
索引,执行跨会话搜索,以检索价格在10到30“单位”之间的商品所在的会话。
Query q = new Query().addFilter(new Query.NumericFilter("price", 10, 30)).setSortBy("price", true).setNoContent();
SearchResult res = client.ftSearch("session_idx", q);
System.out.println("Number of results: " + res.getTotalResults());
List<Document> docs = res.getDocuments();
for (Document doc : docs) {
System.out.println("Found session: " + doc.getId());
}
搜索将检索到以下结果,因为这两个会话中都有价格在此范围内的商品。
Number of results: 2
Found session: session:2
Found session: session:1