Amazon dynamodb 使用AppSync SDK和Amplify CLI通过GSI查询DynamoDB

Amazon dynamodb 使用AppSync SDK和Amplify CLI通过GSI查询DynamoDB,amazon-dynamodb,aws-amplify,aws-appsync,aws-amplify-cli,amazon-dynamodb-index,Amazon Dynamodb,Aws Amplify,Aws Appsync,Aws Amplify Cli,Amazon Dynamodb Index,我正在尝试通过AWS AppSync,使用AWS的 Android AppSync SDK和Amplify CLI。我正在查询一个全球数据库 二级索引(GSI)。我得到一个错误: 表达式块“$[query]”需要一个表达式 我发现了这一点 下面是修复程序。但是,它对我不起作用: 我的schema.graphql是: type olatexOrders @model @key(fields: ["PK", "SK"]) @key(name: "GS

我正在尝试通过AWS AppSync,使用AWS的 Android AppSync SDK和Amplify CLI。我正在查询一个全球数据库 二级索引(GSI)。我得到一个错误:

表达式块“$[query]”需要一个表达式

我发现了这一点 下面是修复程序。但是,它对我不起作用:

我的
schema.graphql
是:

type olatexOrders @model
@key(fields: ["PK", "SK"])
@key(name: "GSI-item-1", fields: ["GSIPKitem1", "GSISKitem1" ], queryField: "olatexOrdersByGSIPKitem1AndGSISKitem1")
@key(name: "GSI-order-1", fields: ["GSIPKorder1", "GSISKorder1" ], queryField: "olatexOrdersByGSIPKorder1AndGSISKorder1")
{
    PK: String!
    SK: String!
    GSIPKitem1: String
    GSISKitem1: String
    GSIPKorder1: String
    GSISKorder1: String
    ... and many more fields not relevant for this case
}
散列键(主键+辅键)和两个GSI(GSI-item-1, GSI-order1)已在DynamoDB中正确创建。我还可以查询我的 使用GSI从AppSync获取DynamoDB表:

query MyQuery {
  olatexOrdersByGSIPKorder1AndGSISKorder1(GSIPKorder1: "IN_PROGRESS") {
    nextToken
    items {
      GSIPKorder1
      GSISKorder1
    }
  }
}
但是,当我尝试在内部使用自动生成的放大类时,它不起作用 我的Android应用程序,如下所示:

private void query(){
AwsClientFactory.getInstance(上下文)
.query(OLETEXORDERSBYGSIPKORDER1和GSISKORDER1query
.builder()
.gSIPKorder1(订单状态为进行中)
.限额(200)
.build())
.responseFetcher(仅适用于AppSyncResponseFetchers.NETWORK_)
.排队(回调);
}
我得到了上面提到的同样的错误。在阅读了相关的 问题,我的理解是有一些 GSI实施方式中的缺陷/不一致/限制 AppSync,因此,您不仅需要指定 GSI,但也包括排序键和排序顺序。有了这些知识,, 为了进行测试,我将函数重写为:

private void query(){
AwsClientFactory.getInstance(上下文)
.query(OLETEXORDERSBYGSIPKORDER1和GSISKORDER1query
.builder()
.gSIPKorder1(订单状态为进行中)
.gSISKorder1(ModelStringKeyConditionInput.builder().beginsWith(“K”).build())
.sortDirection(ModelSortDirection.DESC)
.限额(200)
.build())
.responseFetcher(仅适用于AppSyncResponseFetchers.NETWORK_)
.排队(回调);
}
不幸的是,我仍然遇到同样的错误:

表达式块“$[query]”需要一个表达式

我使用的是Amplify CLI版本4.27.2。 所有的帮助将不胜感激

编辑1
我试图简化我的案子。我创建的GSI只有一列。请参见下面的
schema.graphql

type olatexOrders @model
@key(fields: ["PK", "SK"])
@key(name: "GSI-item-1", fields: ["GSIPKitem1"], queryField: "olatexOrdersByGSIItem")
@key(name: "GSI-order-1", fields: ["GSIPKorder1"], queryField: "olatexOrdersByGSIOrder")
{
    PK: String!
    SK: String!
    GSIPKitem1: String
    GSIPKorder1: String
    ... and many more fields not relevant for this case
}
现在,我尝试使用以下代码通过Amplify&AppSync查询我的dynamo表:

public class GetInProgressOrders {

    private GraphQLCall.Callback<OlatexOrdersByGsiOrderQuery.Data> callback = new GraphQLCall.Callback<OlatexOrdersByGsiOrderQuery.Data>() {
        @Override
        public void onResponse(@Nonnull Response<OlatexOrdersByGsiOrderQuery.Data> response) {
            try{
                Log.d("MyTest", "TST response error: "+errors.get(0).message());
            }
            catch (Exception e){
                Log.e("MyTest", e.getMessage())
            }
        }

        @Override
        public void onFailure(@Nonnull ApolloException e) {
            Log.e("MyTest", e.getMessage())
        }
    };

    private void query(Context context){
        AWSAppSyncClient awsClient = AwsClientFactory.getInstance(context);
        
        OlatexOrdersByGsiOrderQuery tmpQuery = OlatexOrdersByGsiOrderQuery
                .builder()
                .gSIPKorder1(ORDER_STATUS_IN_PROGRESS)
                .build();

        awsClient.query(
                tmpQuery
            )
                .responseFetcher(AppSyncResponseFetchers.NETWORK_ONLY)
                .enqueue(callback);
    }
}
这让我觉得自己做错了什么。基本上我无法通过GSI在Amplify中查询表。不幸的是,我看不出我的错误。

考虑到

这不是确切的答案,而是实际可行的解决方法。
事实证明,我有多个问题,有些更好,有些更糟。我为修复代码所做的事情:

  • 对于从Android应用程序到AWS AppSync的通信,请使用Amplify类,而不是AWSAPSyncClient类
  • 在schema.graphql中,不要只使用大写字母的字段(在我的例子中,使用PK&SK,而使用PK&SK)
  • 在schema.graphql中,不要创建以小写字母开头的类型
  • 创建id的id列!键入(即使您根本不需要)

  • 说到这里,请参见我的schema.graphql,它实际上可以工作:
    type OlatexOrders @model
    
    @key(fields: ["pk", "sk"])
    @key(name: "GSI-item-1", fields: ["gsi_pk_item_1", "gsi_sk_item_1"], queryField: "olatexOrdersByGSIItem")
    @key(name: "GSI-order-1", fields: ["gsi_pk_order_1", "gsi_sk_order_1"], queryField: "olatexOrdersByGSIOrder")
    {
        pk: String!
        sk: String!
        gsi_pk_item_1: String
        gsi_sk_item_1: String
        gsi_pk_order_1: String
        gsi_sk_order_1: String
        ... different not relevant fields
        id: ID!
    }
    
    和我在Android应用程序中的查询:

    Amplify.API.query(
    ModelQuery.list(OlatexOrders.class, OlatexOrders.GSI_PK_ORDER_1.eq(ORDER_STATUS_IN_PROGRESS)),
                    response -> {
                        if(response.hasErrors())
                            Log.i("TestTag", "Errors: " + response.getErrors().get(0));
    
                        if(response.hasData()){
                            for(OlatexOrders orders: response.getData()){
                                inProgressOrdersNames.add(orders.getGsiSkOrder_1());
                            }
                        }
                        else{
                            Log.i("TestTag", "No data");
                        }
                    },
                    error -> Log.e("TestTag", "Error", error)
            );
    
    问候

    Amplify.API.query(
    ModelQuery.list(OlatexOrders.class, OlatexOrders.GSI_PK_ORDER_1.eq(ORDER_STATUS_IN_PROGRESS)),
                    response -> {
                        if(response.hasErrors())
                            Log.i("TestTag", "Errors: " + response.getErrors().get(0));
    
                        if(response.hasData()){
                            for(OlatexOrders orders: response.getData()){
                                inProgressOrdersNames.add(orders.getGsiSkOrder_1());
                            }
                        }
                        else{
                            Log.i("TestTag", "No data");
                        }
                    },
                    error -> Log.e("TestTag", "Error", error)
            );