Closed27

primaryKey を指定して sortKey で Sort したい

AppSync の Resolver をいい感じに設定してあげないといけなさそう

#set( $limit = $util.defaultIfNull($context.args.limit, 100) )
#set( $modelQueryExpression = {} )

#if( !$util.isNull($ctx.args.filter.Id) && !$util.isNull($ctx.args.filter.Id.eq) )
  #set( $modelQueryExpression.expression = "#Id = :Id" )
  #set( $modelQueryExpression.expressionNames = {
  "#Id": "Id"
} )
  #set( $modelQueryExpression.expressionValues = {
  ":Id": {
      "S": "$ctx.args.filter.Id.eq"
  }
} )
#end

#set( $ListRequest = {
  "version": "2018-05-29",
  "limit": $limit,
  "operation": "Query"
} )
#if( $context.args.nextToken )
  #set( $ListRequest.nextToken = $context.args.nextToken )
#end

$util.qr($ListRequest.put("query", $modelQueryExpression))
#set( $ListRequest.scanIndexForward = false )

$util.toJson($ListRequest)

Id 一致で降順でとってくる

query ListPosts(
    $filter: TablePostsFilterInput
    $limit: Int
    $nextToken: String
)

クエリはこんな感じ

query ListPosts(
    $filter: TablePostsFilterInput
    $limit: Int
    $nextToken: String
)

クエリはこんな感じ

通ったクエリをおいておく

#set( $limit = $util.defaultIfNull($context.args.limit, 100) )
#set( $QueryRequest = {
  "version": "2017-02-28",
  "operation": "Scan",
  "limit": $limit
} )
#if( $context.args.nextToken ) #set( $QueryRequest.nextToken = "$context.args.nextToken" ) #end
#if( $context.args.filter ) #set( $QueryRequest.filter = $util.parseJson("$util.transform.toDynamoDBFilterExpression($ctx.args.filter)") ) #end
$util.toJson($QueryRequest)
#set( $limit = $util.defaultIfNull($context.args.limit, 100) )

#set( $modelQueryExpression = {} )

#if( !$util.isNull($ctx.args.filter.id) && !$util.isNull($ctx.args.filter.id.eq) )
  #set( $modelQueryExpression.expression = "#id = :id" )
  #set( $modelQueryExpression.expressionNames = {
  "#id": "id"
} )
  #set( $modelQueryExpression.expressionValues = {
  ":id": {
      "S": "$ctx.args.filter.id.eq"
  }
} )
#end

#set( $QueryRequest = {
  "version": "2017-02-28",
  "limit": $limit
} )
#if( $context.args.nextToken ) #set( $QueryRequest.nextToken = "$context.args.nextToken" ) #end
#if( $context.args.filter ) #set( $QueryRequest.filter = $util.parseJson("$util.transform.toDynamoDBFilterExpression($ctx.args.filter)") ) #end
$util.qr($ListRequest.put("query", $modelQueryExpression))
#if( !$util.isNull($ctx.args.filter.id) && !$util.isNull($ctx.args.filter.id.eq) )
  #set( $QueryRequest.operation = "Query" )
  #set( $ListRequest.scanIndexForward = false )
#else
  #set( $QueryRequest.operation = "Scan" )
#end
$util.toJson($QueryRequest)

動いた

動いてなかった

## limit が設定されていなければ 100 にする
#set( $limit = $util.defaultIfNull($context.args.limit, 100) )

#set( $modelQueryExpression = {} )

## filter に id の一致検索が入っていたら、クエリを作る
#if( !$util.isNull($ctx.args.filter.id) && !$util.isNull($ctx.args.filter.id.eq) )
  #set( $modelQueryExpression.expression = "#id = :id" )
  #set( $modelQueryExpression.expressionNames = {
  "#id": "id"
} )
  #set( $modelQueryExpression.expressionValues = {
  ":id": {
      "S": "$context.args.filter.id.eq"
  }
} )
#end

#set( $QueryRequest = {
  "version": "2017-02-28",
  "limit": $limit
} )
#if( $context.args.nextToken )
  #set( $QueryRequest.nextToken = "$context.args.nextToken" )
#end

#if( $context.args.filter )
  #set( $QueryRequest.filter = $util.parseJson("$util.transform.toDynamoDBFilterExpression($context.args.filter)") )
#end

$util.qr($ListRequest.put("query", $modelQueryExpression))

## id の一致指定があれば Query, なければ Scan を投げる
#if( !$util.isNull($ctx.args.filter.id) && !$util.isNull($context.args.filter.id.eq) )
  #set( $QueryRequest.operation = "Query" )
  #set( $ListRequest.scanIndexForward = false )
#else
  #set( $QueryRequest.operation = "Scan" )
#end

$util.toJson($QueryRequest)

ctx -> context

#set( $limit = $util.defaultIfNull($context.args.limit, 100) )

#set( $modelQueryExpression = {} )

#if( !$util.isNull($context.args.filter.id) && !$util.isNull($context.args.filter.id.eq) )
  #set( $modelQueryExpression.expression = "#id = :id" )
  #set( $modelQueryExpression.expressionNames = {
    "#id": "id"
  } )
  #set( $modelQueryExpression.expressionValues = {
    ":id": {
        "S": "$context.args.filter.id.eq"
    }
  } )
#end

#if( !$util.isNull($context.args.filter.timestampMs) && !$util.isNull($context.args.filter.timestampMs.eq) )
  #set( $modelQueryExpression.expression = "$modelQueryExpression.expression AND #sortKey = :sortKey" )
  $util.qr($modelQueryExpression.expressionNames.put("#sortKey", "timestampMs"))
  $util.qr($modelQueryExpression.expressionValues.put(":sortKey", { "N": "$context.args.filter.timestampMs.eq" }))
#end
#if( !$util.isNull($context.args.filter.timestampMs) && !$util.isNull($context.args.filter.timestampMs.ge) )
  #set( $modelQueryExpression.expression = "$modelQueryExpression.expression AND #sortKey >= :sortKey" )
  $util.qr($modelQueryExpression.expressionNames.put("#sortKey", "timestampMs"))
  $util.qr($modelQueryExpression.expressionValues.put(":sortKey", { "N": "$context.args.filter.timestampMs.ge" }))
#end

#set( $QueryRequest = {
  "version": "2017-02-28",
  "limit": $limit
} )

#if( $context.args.nextToken )
  #set( $QueryRequest.nextToken = "$context.args.nextToken" )
#end

#if( !$util.isNull($context.args.filter.id) && !$util.isNull($context.args.filter.id.eq) )
  #set( $QueryRequest.operation = "Query" )
  #set( $QueryRequest.scanIndexForward = false )
  $util.qr($QueryRequest.put("query", $modelQueryExpression))
#else
  #set( $QueryRequest.operation = "Scan" )
#end

$util.toJson($QueryRequest)

sortKey の指定を入れた

"S": "$context.args.filter.id.eq"

この S とか N とか何かと思ってたら、
String, Number か

#set( $limit = $util.defaultIfNull($context.args.limit, 100) )

#set( $modelQueryExpression = {} )

#if( !$util.isNull($context.args.filter.id) && !$util.isNull($context.args.filter.id.eq) )
  #set( $modelQueryExpression.expression = "#id = :id" )
  #set( $modelQueryExpression.expressionNames = {
    "#id": "id"
  } )
  #set( $modelQueryExpression.expressionValues = {
    ":id": {
        "S": "$context.args.filter.id.eq"
    }
  } )
#end

#if( !$util.isNull($context.args.filter.timestampMs) && !$util.isNull($context.args.filter.timestampMs.eq) )
  #set( $modelQueryExpression.expression = "$modelQueryExpression.expression AND #sortKey = :sortKey" )
  $util.qr($modelQueryExpression.expressionNames.put("#sortKey", "timestampMs"))
  $util.qr($modelQueryExpression.expressionValues.put(":sortKey", { "N": "$context.args.filter.timestampMs.eq" }))
#end
#if( !$util.isNull($context.args.filter.timestampMs) && !$util.isNull($context.args.filter.timestampMs.ge) )
  #set( $modelQueryExpression.expression = "$modelQueryExpression.expression AND #sortKey >= :sortKey" )
  $util.qr($modelQueryExpression.expressionNames.put("#sortKey", "timestampMs"))
  $util.qr($modelQueryExpression.expressionValues.put(":sortKey", { "N": "$context.args.filter.timestampMs.ge" }))
#end

#set( $QueryRequest = {
  "version": "2017-02-28",
  "limit": $limit
} )

#if( $context.args.nextToken )
  #set( $QueryRequest.nextToken = "$context.args.nextToken" )
#end

#if( !$util.isNull($context.args.filter.id) && !$util.isNull($context.args.filter.id.eq) )
  #set( $QueryRequest.operation = "Query" )
  #set( $QueryRequest.scanIndexForward = false )
  $util.qr($QueryRequest.put("query", $modelQueryExpression))
#else
  #set( $QueryRequest.operation = "Scan" )
  #set( $QueryRequest.filter =  #if($context.args.filter) $util.transform.toDynamoDBFilterExpression($context.args.filter) #else null #end)
#end

$util.toJson($QueryRequest)

ScanのときにFilterを使うように

何かがだめっぽい

#set( $limit = $util.defaultIfNull($context.args.limit, 100) )

#set( $modelQueryExpression = {} )

#if( !$util.isNull($context.args.filter.id) && !$util.isNull($context.args.filter.id.eq) )
  #set( $modelQueryExpression.expression = "#id = :id" )
  #set( $modelQueryExpression.expressionNames = {
  "#id": "id"
} )
  #set( $modelQueryExpression.expressionValues = {
  ":id": {
      "S": "$context.args.filter.id.eq"
  }
} )
#end

#if( !$util.isNull($context.args.filter.timestampMs) && !$util.isNull($context.args.filter.timestampMs.eq) )
  #set( $modelQueryExpression.expression = "$modelQueryExpression.expression AND #sortKey = :sortKey" )
  $util.qr($modelQueryExpression.expressionNames.put("#sortKey", "timestampMs"))
  $util.qr($modelQueryExpression.expressionValues.put(":sortKey", { "N": "$context.args.filter.timestampMs.eq" }))
#end
#if( !$util.isNull($context.args.filter.timestampMs) && !$util.isNull($context.args.filter.timestampMs.ge) )
  #set( $modelQueryExpression.expression = "$modelQueryExpression.expression AND #sortKey >= :sortKey" )
  $util.qr($modelQueryExpression.expressionNames.put("#sortKey", "timestampMs"))
  $util.qr($modelQueryExpression.expressionValues.put(":sortKey", { "N": "$context.args.filter.timestampMs.ge" }))
#end

#set( $QueryRequest = {
  "version": "2017-02-28",
  "limit": $limit
} )

#if( $context.args.nextToken ) #set( $QueryRequest.nextToken = "$context.args.nextToken" ) #end

#if( !$util.isNull($context.args.filter.id) )
  #set( $QueryRequest.operation = "Query" )
  #set( $QueryRequest.scanIndexForward = false )
  $util.qr($QueryRequest.put("query", $modelQueryExpression))
#else
  #set( $QueryRequest.operation = "Scan" )
#end

#if( !$util.isNull($context.args.filter) )
 $util.qr( $QueryRequest.put("filter", $util.transform.toDynamoDBFilterExpression($context.args.filter)) )
#end

$util.toJson($QueryRequest)
{
  "data": {
    "xxxxxxxxxxxx": null
  },
  "errors": [
    {
      "path": [
        "xxxxxxxxxxxx"
      ],
      "data": null,
      "errorType": "MappingTemplate",
      "errorInfo": null,
      "locations": [
        {
          "line": 2,
          "column": 3,
          "sourceName": null
        }
      ],
      "message": "Expected JSON object for '$[filter]' but got a 'STRING' instead."
    }
  ]
}

何が違うのかがわからない

#set( $limit = $util.defaultIfNull($context.args.limit, 100) )

#set( $modelQueryExpression = {} )

#if( !$util.isNull($context.args.filter.id) && !$util.isNull($context.args.filter.id.eq) )
  #set( $modelQueryExpression.expression = "#id = :id" )
  #set( $modelQueryExpression.expressionNames = {
  "#id": "id"
} )
  #set( $modelQueryExpression.expressionValues = {
  ":id": {
      "S": "$context.args.filter.id.eq"
  }
} )
#end

#if( !$util.isNull($context.args.filter.timestampMs) && !$util.isNull($context.args.filter.timestampMs.eq) )
  #set( $modelQueryExpression.expression = "$modelQueryExpression.expression AND #sortKey = :sortKey" )
  $util.qr($modelQueryExpression.expressionNames.put("#sortKey", "timestampMs"))
  $util.qr($modelQueryExpression.expressionValues.put(":sortKey", { "N": "$context.args.filter.timestampMs.eq" }))
#end
#if( !$util.isNull($context.args.filter.timestampMs) && !$util.isNull($context.args.filter.timestampMs.ge) )
  #set( $modelQueryExpression.expression = "$modelQueryExpression.expression AND #sortKey >= :sortKey" )
  $util.qr($modelQueryExpression.expressionNames.put("#sortKey", "timestampMs"))
  $util.qr($modelQueryExpression.expressionValues.put(":sortKey", { "N": "$context.args.filter.timestampMs.ge" }))
#end

#set( $QueryRequest = {
  "version": "2017-02-28",
  "limit": $limit
} )

#if( $context.args.nextToken ) #set( $QueryRequest.nextToken = "$context.args.nextToken" ) #end

#if( !$util.isNull($context.args.filter.id) )
  #set( $QueryRequest.operation = "Query" )
  #set( $QueryRequest.scanIndexForward = false )
  $util.qr($QueryRequest.put("query", $modelQueryExpression))
#else
  #set( $QueryRequest.operation = "Scan" )
#end

#if( $context.args.filter ) #set( $QueryRequest.filter = $util.parseJson("$util.transform.toDynamoDBFilterExpression($ctx.args.filter)") ) #end

$util.toJson($QueryRequest)

通った

だめだ。クエリが効かなくなった

"Filter Expression can only contain non-primary key attributes: Primary key attribute: id (Service: DynamoDb, Status Code: 400, Request ID: XXXXXX, Extended Request ID: null)"

filter から primary key を外せってことかな

#set( $limit = $util.defaultIfNull($context.args.limit, 100) )

#set( $modelQueryExpression = {} )

#if( !$util.isNull($context.args.filter.id) && !$util.isNull($context.args.filter.id.eq) )
  #set( $modelQueryExpression.expression = "#id = :id" )
  #set( $modelQueryExpression.expressionNames = {
  "#id": "id"
} )
  #set( $modelQueryExpression.expressionValues = {
  ":id": {
      "S": "$context.args.filter.id.eq"
  }
} )
#end

#if( !$util.isNull($context.args.filter.timestampMs) && !$util.isNull($context.args.filter.timestampMs.eq) )
  #set( $modelQueryExpression.expression = "$modelQueryExpression.expression AND #sortKey = :sortKey" )
  $util.qr($modelQueryExpression.expressionNames.put("#sortKey", "timestampMs"))
  $util.qr($modelQueryExpression.expressionValues.put(":sortKey", { "N": "$context.args.filter.timestampMs.eq" }))
#end
#if( !$util.isNull($context.args.filter.timestampMs) && !$util.isNull($context.args.filter.timestampMs.ge) )
  #set( $modelQueryExpression.expression = "$modelQueryExpression.expression AND #sortKey >= :sortKey" )
  $util.qr($modelQueryExpression.expressionNames.put("#sortKey", "timestampMs"))
  $util.qr($modelQueryExpression.expressionValues.put(":sortKey", { "N": "$context.args.filter.timestampMs.ge" }))
#end

#set( $QueryRequest = {
  "version": "2017-02-28",
  "limit": $limit
} )

#if( $context.args.nextToken ) #set( $QueryRequest.nextToken = "$context.args.nextToken" ) #end

#if( !$util.isNull($context.args.filter.id) )
  #set( $QueryRequest.operation = "Query" )
  #set( $QueryRequest.scanIndexForward = false )
  $util.qr($QueryRequest.put("query", $modelQueryExpression))
#else
  #set( $QueryRequest.operation = "Scan" )
  #if( $context.args.filter ) #set( $QueryRequest.filter = $util.parseJson("$util.transform.toDynamoDBFilterExpression($ctx.args.filter)") ) #end
#end

$util.toJson($QueryRequest)

scan のときだけ filter を呼び出す妥協案

query のときも付加条件で filter したい

全部 filter でやろうとしてるから詰まってる説

key は $context.args.id の形で
filter は $context.args.filter で取る
ってすれば、filter に key が入り込むことはなさそう

## [Start] Set query expression for @key **
#set( $modelQueryExpression = {} )

#if( !$util.isNull($ctx.args.id) )
  #set( $modelQueryExpression.expression = "#id = :id" )
  #set( $modelQueryExpression.expressionNames = {
  "#id": "id"
} )
  #set( $modelQueryExpression.expressionValues = {
  ":id": {
      "S": "$ctx.args.id"
  }
} )
#end
## [Start] Applying Key Condition **
#if( !$util.isNull($ctx.args.timestamp) && !$util.isNull($ctx.args.timestamp.beginsWith) )
  #set( $modelQueryExpression.expression = "$modelQueryExpression.expression AND begins_with(#sortKey, :sortKey)" )
  $util.qr($modelQueryExpression.expressionNames.put("#sortKey", "timestamp"))
  $util.qr($modelQueryExpression.expressionValues.put(":sortKey", { "N": "$ctx.args.timestamp.beginsWith" }))
#end
#if( !$util.isNull($ctx.args.timestamp) && !$util.isNull($ctx.args.timestamp.between) )
  #set( $modelQueryExpression.expression = "$modelQueryExpression.expression AND #sortKey BETWEEN :sortKey0 AND :sortKey1" )
  $util.qr($modelQueryExpression.expressionNames.put("#sortKey", "timestamp"))
  $util.qr($modelQueryExpression.expressionValues.put(":sortKey0", { "N": "$ctx.args.timestamp.between[0]" }))
  $util.qr($modelQueryExpression.expressionValues.put(":sortKey1", { "N": "$ctx.args.timestamp.between[1]" }))
#end
#if( !$util.isNull($ctx.args.timestamp) && !$util.isNull($ctx.args.timestamp.eq) )
  #set( $modelQueryExpression.expression = "$modelQueryExpression.expression AND #sortKey = :sortKey" )
  $util.qr($modelQueryExpression.expressionNames.put("#sortKey", "timestamp"))
  $util.qr($modelQueryExpression.expressionValues.put(":sortKey", { "N": "$ctx.args.timestamp.eq" }))
#end
#if( !$util.isNull($ctx.args.timestamp) && !$util.isNull($ctx.args.timestamp.lt) )
  #set( $modelQueryExpression.expression = "$modelQueryExpression.expression AND #sortKey < :sortKey" )
  $util.qr($modelQueryExpression.expressionNames.put("#sortKey", "timestamp"))
  $util.qr($modelQueryExpression.expressionValues.put(":sortKey", { "N": "$ctx.args.timestamp.lt" }))
#end
#if( !$util.isNull($ctx.args.timestamp) && !$util.isNull($ctx.args.timestamp.le) )
  #set( $modelQueryExpression.expression = "$modelQueryExpression.expression AND #sortKey <= :sortKey" )
  $util.qr($modelQueryExpression.expressionNames.put("#sortKey", "timestamp"))
  $util.qr($modelQueryExpression.expressionValues.put(":sortKey", { "N": "$ctx.args.timestamp.le" }))
#end
#if( !$util.isNull($ctx.args.timestamp) && !$util.isNull($ctx.args.timestamp.gt) )
  #set( $modelQueryExpression.expression = "$modelQueryExpression.expression AND #sortKey > :sortKey" )
  $util.qr($modelQueryExpression.expressionNames.put("#sortKey", "timestamp"))
  $util.qr($modelQueryExpression.expressionValues.put(":sortKey", { "N": "$ctx.args.timestamp.gt" }))
#end
#if( !$util.isNull($ctx.args.timestamp) && !$util.isNull($ctx.args.timestamp.ge) )
  #set( $modelQueryExpression.expression = "$modelQueryExpression.expression AND #sortKey >= :sortKey" )
  $util.qr($modelQueryExpression.expressionNames.put("#sortKey", "timestamp"))
  $util.qr($modelQueryExpression.expressionValues.put(":sortKey", { "N": "$ctx.args.timestamp.ge" }))
#end
## [End] Applying Key Condition **
## [End] Set query expression for @key **
#set( $limit = $util.defaultIfNull($context.args.limit, 20) )
#set( $QueryRequest = {
  "version": "2017-02-28",
  "limit": $limit,
} )

#if( $context.args.nextToken ) #set( $QueryRequest.nextToken = "$context.args.nextToken" ) #end
#if( $context.args.filter ) #set( $QueryRequest.filter = $util.parseJson("$util.transform.toDynamoDBFilterExpression($ctx.args.filter)") ) #end

#if( !$util.isNull($context.args.id) )
  #set( $QueryRequest.operation = "Query" )
  #set( $QueryRequest.scanIndexForward = false )
  $util.qr($QueryRequest.put("query", $modelQueryExpression))
#else
  #set( $QueryRequest.operation = "Scan" )
#end

$util.toJson($QueryRequest)

key があったら query、そうでなければ scan

このスクラップは2021/04/25にクローズされました
ログインするとコメントできます