gpt4 book ai didi

java - 带有 Long 类型键的 spring data redis zadd 不起作用

转载 作者:可可西里 更新时间:2023-11-01 11:23:24 27 4
gpt4 key购买 nike

我在这里尝试通过做一些例子来学习 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/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com