-1

我正在尝试使用 AWS 的 Android AppSync SDK 和 Amplify CLI 通过 AWS AppSync 查询 DynamoDB 表。我正在查询全球二级索引 (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
}

在 DynamoDB 中正确创建了哈希键(主键 + 辅助键)和两个 GSI(GSI-item-1、GSI-order1)。我还可以使用 GSI 从 AppSync 查询我的 DynamoDB 表:

query MyQuery {
  olatexOrdersByGSIPKorder1AndGSISKorder1(GSIPKorder1: "IN_PROGRESS") {
    nextToken
    items {
      GSIPKorder1
      GSISKorder1
    }
  }
}

但是,当我尝试在我的 Android 应用程序中使用自动生成的放大类时,它不起作用,如下所示:

private void query() {
    AwsClientFactory.getInstance(context)
        .query(OlatexOrdersByGsipKorder1AndGsisKorder1Query
            .builder()
            .gSIPKorder1(ORDER_STATUS_IN_PROGRESS)
            .limit(200)
            .build())
        .responseFetcher(AppSyncResponseFetchers.NETWORK_ONLY)
        .enqueue(callback);
}

我遇到了上面提到的同样的错误。阅读相关问题后,我的理解是在 AppSync 中实现 GSI 的方式存在一些错误/不一致/限制,因此您不仅需要指定 GSI 的主键,还需要指定排序键和排序顺序为出色地。有了这些知识,为了测试,我将我的函数重写为:

private void query() {
    AwsClientFactory.getInstance(context)
        .query(OlatexOrdersByGsipKorder1AndGsisKorder1Query
            .builder()
            .gSIPKorder1(ORDER_STATUS_IN_PROGRESS)
            .gSISKorder1(ModelStringKeyConditionInput.builder().beginsWith("K").build())
            .sortDirection(ModelSortDirection.DESC)
            .limit(200)
            .build())
        .responseFetcher(AppSyncResponseFetchers.NETWORK_ONLY)
        .enqueue(callback);
}

不幸的是,我仍然遇到同样的错误:

表达式块 '$[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 查询我的发电机表:

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);
    }
}

上面的执行最终会出现与以前相同的错误:

TST response error: Expression block '$[query]' requires an expression

这让我觉得我做错了什么。基本上我无法通过 GSI 在 Amplify 中查询表。不幸的是,我没有看到我的错误。
问候

4

1 回答 1

-1

这并不完全是答案,而是真正有效的解决方法。
事实证明,我有多个问题,有些记录得更好,有些更糟。我为修复代码所做的事情:

  1. 对于从 Android 应用程序到 AWS AppSync 的通信,请使用 Amplify 类,而不是使用 AWSAppSyncClient 类。
  2. 在 schema.graphql 中,不要仅使用大写字母的字段(在我的情况下,使用 PK 和 SK 使用 pk 和 sk)
  3. 在 schema.graphql 不要创建以小写开头的类型
  4. 创建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 App 中的查询:

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)
        );

问候!

于 2020-12-17T22:50:08.243 回答