- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我在这里尝试通过做一些例子来学习 Redis。我有一个名为 DriverLocation
的实体,其中有一个名为 updatedAt
的时间戳,这是一个以毫秒表示的纪元时间。关键是我想要一个 SortedSet,这样我就可以执行 zrangebyscore
查询,以获取按时间戳排序的最后 N 条记录。
sortedset 基本上会有timestamp --> hash_id
结构。如果我想获取最后 10 分钟添加的记录,那么我将执行 zrangebyscore
查询以按排序方式获取所有 hash_id。然后使用带有 hash_ids 的 hmget
获取所有哈希对象。
这是关于 redis-cli 的一个非常简单的工作演示,您可以假设我使用了 3 位数字而不是毫秒。
localhost:6379> zadd locations_0 213 hash_id_1
(integer) 1
localhost:6379> zadd locations_0 214 hash_id_2
(integer) 1
localhost:6379> zadd locations_0 215 hash_id_3
(integer) 1
localhost:6379> zrangebyscore locations_0 212 214
1) "hash_id_1"
2) "hash_id_2"
redis cli 上一切正常。但是,在 Spring 方面,我无法实现我的目标。
DriverLocation.java
@RedisHash("driverLocation")
@Data
@AllArgsConstructor
@NoArgsConstructor
public class DriverLocationEntity {
@Id
private Long id;
@Indexed
private Long driverId;
@GeoIndexed
private Point point;
private Date updatedAt;
}
RedisConfiguration.java
@Configuration
@EnableRedisRepositories
public class RedisConfiguration {
@Value("${spring.redis.host}")
private String redisHost;
@Value("${spring.redis.port}")
private int redisPort;
@Bean
public LettuceConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(redisHost, redisPort);
}
@Bean
public RedisTemplate<Object, Object> redisTemplate() {
RedisTemplate<Object, Object> template = new RedisTemplate<>();
template.setConnectionFactory(redisConnectionFactory());
return template;
}
@Bean
public RedisAtomicLong redisAtomicLong() {
RedisAtomicLong redisAtomicLong = new RedisAtomicLong("DriverLocationIdCounter", redisConnectionFactory(), 0L);
return redisAtomicLong;
}
}
Controller.java
@RestController
@RequestMapping("/drivers")
@Slf4j
public class DriverLocationController {
@Autowired
private DriverLocationRepository driverLocationRepository;
@Autowired
private RedisTemplate<Object, Object> redisTemplate;
@Autowired
private RedisAtomicLong redisAtomicLong;
@Autowired
private ObjectMapper objectMapper;
@RequestMapping("/{id}")
public ResponseEntity<List<DriverLocationEntity>> getDriver(@PathVariable("id") Long driverId) {
long now = Instant.now().getEpochSecond();
Set<Object> ids = redisTemplate.opsForZSet().rangeByScore(
"locations_" + driverId,
Instant.ofEpochSecond(now).minusSeconds(300).toEpochMilli(),
Instant.ofEpochSecond(now).toEpochMilli());
List<Object> driverLocations = redisTemplate.opsForHash().multiGet("driverLocations", ids.stream().map(id -> (Long) id).collect(Collectors.toList()));
return ResponseEntity.status(HttpStatus.OK).body(driverLocations.stream().map(dLoc -> (DriverLocationEntity) dLoc).collect(Collectors.toList()));
}
@RequestMapping(value = "/{id}", method = RequestMethod.POST)
public ResponseEntity<String> addDriverLocation(@RequestBody DriverLocationMessageEntity messageEntity,
@PathVariable("id") Long driverId) throws JsonProcessingException {
long now = Instant.now().toEpochMilli();
DriverLocationEntity driverLocationEntity = new DriverLocationEntity();
driverLocationEntity.setDriverId(driverId);
driverLocationEntity.setPoint(new Point(messageEntity.getLongitude(), messageEntity.getLatitude()));
driverLocationEntity.setUpdatedAt(new Date(now));
driverLocationEntity.setId(redisAtomicLong.getAndIncrement());
String strVal = objectMapper.writeValueAsString(driverLocationEntity);
// save driver location entity
driverLocationRepository.save(driverLocationEntity);
// save timestamp -> hash_id
redisTemplate.opsForZSet().add("locations_" + driverLocationEntity.getDriverId(), now, driverLocationEntity.getId());
return ResponseEntity.status(HttpStatus.OK).body("done");
}
}
感谢您的帮助。
最佳答案
我基本上是通过使用 Redisson 来管理的客户端及其 StringCodec
DriverLocationEntity driverLocationEntity = new DriverLocationEntity();
driverLocationEntity.setDriverId(messageEntity.getDriverId());
driverLocationEntity.setPoint(new Point(messageEntity.getLongitude(), messageEntity.getLatitude()));
driverLocationEntity.setUpdatedAt(new Date(now));
driverLocationEntity.setId(UUID.randomUUID().toString());
// add hash_id into geoset for distance calculations
redissonClient.getGeo(GEO_SET_KEY_NAME, new StringCodec()).add(messageEntity.getLongitude(), messageEntity.getLatitude(), HASH_ID_PREFIX + driverLocationEntity.getId());
关于java - 带有 Long 类型键的 spring data redis zadd 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56918372/
我正在使用 ioredis 来缓存和索引大量数据,到目前为止,我还没有找到任何文档表明我可以通过一次调用执行多个 SADD。 这是否可能,如果可能,它有什么性能优势吗?目前,我正在使用 multi()
如果记录首先不存在,我正在尝试将带有分数的记录添加到排序集中: func (r *rDA) InsertIntoSortedSetIfNotExist(value int32, score int32
是否有可能(或者是否有另一种惯用的方式)ZADD 一个分数为最高现有分数加一的成员? 例如: > FLUSHDB > ZADD key 1 one > ZADD key * mem > ZSCORE
我正在尝试将多个键值对添加到排序集中,如下所示: local status_and_score = redis.call('zrevrange', 'time_1', 0, 100, 'WITH
我需要为添加到集合中的每个键存储最低的分数,但是当我执行ZADD时,即使分数更高,Redis也会用新值覆盖分数。 ZADD myorderset 1 'one' 2 'two' 3 'three' (
如果添加到有序集合 (redis) 中的每个值都是得分最高的值,那么每个 zadd 的时间复杂度是否为 O(log(N)) >? 或者,对于这种边缘情况,redis 执行优化(例如,在 score 高
我正在尝试使用 Redis 进行实时搜索查询。阅读下面提到的文章后,我尝试了 python 脚本,它运行良好。但是在数据库中,我有两个字段: i) country_name ii) country_i
是否有可能 - 在 redis 集群环境中执行 ZADD 时 - 所有添加的键最终都不会同时对所有人可用? 我们使用 (scala) redis 客户端通过 ZADD 添加一批 key 。然后在 X
我想使用 redis 来存储这样的数据:{id: timestamp(1416991171)} 在一个排序集中,它需要有一个最大长度。 我只是在插入新的成员/值对之前检查排序集的长度。但我不确定这是否
我刚开始使用 Predis 进行 Redis 迁移,但我无法让 zadd 函数处理数组。 此代码有效: foreach ($userIndexArr as $row) { $usernames[]
我在 node.js 中有这一行,但我得到了错误的参数数量。在 redis-cli 中,这很容易,etg test 10 2,但出于某种原因,它在这里不起作用。 例子: convensation:co
我想弄清楚如何通过 phpredis zadd 方法将多个项目添加到 zset。类似下面的内容 ZADD myzset 2 "二"3 "三" 最佳答案 根据documentation ,你可以传递分数
我目前正在将组分配给一个特殊的 url,并将他们的 groupId 作为分数。 创建群组网址: $this->cache->redis->zadd("group_route",$groupI
这个问题在这里已经有了答案: Is Redis list or set pop method thread safe? (1 个回答) 关闭 6 年前。 如果两个 Redis 客户端同时发出 ZAD
我需要 BRPOP,然后使用 ZADD 将弹出的值添加到排序集中。我看到了两个解决方案(我使用的是 Ruby): 编写执行这两个操作的 Lua 脚本。但是,Lua 脚本不能阻塞,因为它们会同时占用整个
redis documentation对于 ZADD 状态,操作是 O(log N)。 但是,有谁知道当插入的元素位于排序顺序的开头或结尾时,ZADD 是否优于 O(log N)? 例如对于某些实现,
我有以下代码: var db = require("redis"); var dbclient1 = db.createClient(); dbclient1.zadd("myprivateset",
我正在尝试使用 laravel redis 为 ZADD 设置选项,但失败了。 我需要设置的选项是NX,如文档中所述: ZADD options (Redis 3.0.2 or greater) ZA
我想使用单个 ZADD 或 HMGET 命令而不是 MULTI/EXEC。 ZADD 可以处理的(分数、成员)元组的数量是否有限制? HMGET 可以处理的字段数有没有限制? 最佳答案 理论极限相当高
我在这里尝试通过做一些例子来学习 Redis。我有一个名为 DriverLocation 的实体,其中有一个名为 updatedAt 的时间戳,这是一个以毫秒表示的纪元时间。关键是我想要一个 Sort
我是一名优秀的程序员,十分优秀!