You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用DynamoDB Enhanced API通过LSI查询返回异常结果求助

DynamoDB Enhanced Client LSI查询异常结果排查

问题背景

我是DynamoDB新手,使用DynamoDB Enhanced Client API通过LSI查询数据时未得到预期结果。已创建以PK为分区键、seatId为排序键的LSI,索引名称为seatId-index。

测试场景

表内有两条PK相同但seatId(LSI排序键)不同的记录,当查询特定PK和seatId时,却返回了这两条记录。

代码片段

实体类代码

@DynamoDbBean
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Data
public class PassengerEntity {

    private String pk;
    private String sk;
    private String seatId;

    @DynamoDbPartitionKey
    @DynamoDbAttribute(value = "PK")
    public String getPk() {
        return pk;
    }
    public void setPk(String pk) {
        this.pk = pk;
    }

    @DynamoDbSortKey
    @DynamoDbAttribute(value = "SK")
    public String getSk() {
        return sk;
    }
    public void setSk(String sk) {
        this.sk = sk;
    }

    @DynamoDbSecondarySortKey(indexNames = "seatId-index")
    public String getSeatId() {
        return seatId;
    }
    public void setSeatId(String seatId) {
        this.seatId = seatId;
    }
}

查询方法代码

public Optional<PassengerEntity> getPassengerDetailsByBookingFlightlegAndSeatId(String pk, String seatId) {
        Optional<PassengerEntity> passengerDetail = Optional.empty();
        DynamoIndex lsiIndex1 = dynamoTableConfig.getDepartureData().getLsiIndex1();

        DynamoDbIndex<PassengerEntity> seatIndex = passengerDetailTable.index(lsiIndex1.getIndexName());

        QueryConditional seatIndexQuery = QueryConditional.keyEqualTo(Key.builder()
                .partitionValue(pk)
                .sortValue(seatId)
                .build());

      SdkIterable<Page<PassengerEntity>> results = seatIndex.query(QueryEnhancedRequest.builder()
          .queryConditional(seatIndexQuery)
          .build());

      for (Page<PassengerEntity> page:results) {
          if (!page.items().isEmpty()) {
              passengerDetail = Optional.of(page.items().get(0));
          }
      }

      return passengerDetail;
    }

问题排查与解决方案

核心问题

代码缺少对LSI分区键的显式映射配置。虽然用@DynamoDbSecondarySortKey标注了seatId作为LSI的排序键,但未指定该LSI的分区键。DynamoDB的LSI必须与主表共享分区键,但Enhanced Client需要明确注解才能正确识别索引结构。

修复步骤

  1. 修正实体类注解
    在pk的get方法上添加@DynamoDbSecondaryPartitionKey注解,关联目标LSI名称:

    @DynamoDbPartitionKey
    @DynamoDbAttribute(value = "PK")
    @DynamoDbSecondaryPartitionKey(indexNames = "seatId-index")
    public String getPk() {
        return pk;
    }
    

    该注解会告知Enhanced Client,PK字段同时是seatId-index这个LSI的分区键。

  2. 验证查询逻辑
    修正注解后,现有查询逻辑是正确的:keyEqualTo指定分区键和排序键的精确匹配,只会返回符合条件的单条记录。

额外注意事项

  • 确保LSI实际结构(分区键、排序键)与注解配置完全一致,包括属性名称(比如表中PK字段名为PK,注解value需对应)。
  • 若问题仍存在,可开启DynamoDB SDK日志,查看实际发送的查询请求,确认参数是否正确传递到服务端。

内容的提问来源于stack exchange,提问作者Prasad Doradla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 04:37:43