简体   繁体   中英

AppSync/GraphQL filter nested objects

I have a DynamoDB table with the following structure

site           (String)
addresses      (List)
 |-> address   (String)
 |-> isCurrent (Boolean)

I want to filter a specific site for either current or all address(s).

query MyQuery {
  getSite(site: "site1", isCurrent: true) {
    site
    addresses{
       adress
       isCurrent
    }

the schema looks like

type Sites{
site: String!
addresses: [Address]
}

type Address {
address: String
isCurrent: Boolean
}

type Query{
getSite(site: String!, isCurrent:Boolean)
}

The Resolver I have

#if($ctx.args.isCurrent)
{
    "version": "2017-02-28",
    "operation": "Query",
    "query": {. // Filter for specific Site
        "expression": "#siteName = :siteNameByUser",
        "expressionNames": {
            "#siteName": "site"
        },
        "expressionValues": {
            ":siteNameByUser": {"S": $util.toJson($ctx.args.site)}
        }
    }, // Filter Current Address(s)
        "filter": {
        "expression": "addresses.isCurrent = :isActiveByUser",
        "expressionValues": {
            ":isActiveByUser": $util.dynamodb.toDynamoDBJson($ctx.args.isCurrent)      
    }
  }
}
#else
{
    "version": "2017-02-28",
    "operation": "GetItem",
    "key": {
        "site": $util.dynamodb.toDynamoDBJson($ctx.args.site)
    }
}
#end

I'm not getting any results when I add filter ( it works without the filter or with isCurrent=False ). I am trying to filter the inner objects in Addresses list based on a value user sends for isCurrent. Any help is much appreciated!

I tried writing a resolver with a filter condition on an inner value (addresses.isCurrent).

{
    "version": "2017-02-28",
    "operation": "Query",
    "query": {. // Filter for specific Site
        "expression": "#siteName = :siteNameByUser",
        "expressionNames": {
            "#siteName": "site"
        },
        "expressionValues": {
            ":siteNameByUser": {"S": $util.toJson($ctx.args.site)}
        }
    }, // Filter Current Address(s)
        "filter": {
        "expression": "addresses.isCurrent = :isActiveByUser",
        "expressionValues": {
            ":isActiveByUser": $util.dynamodb.toDynamoDBJson($ctx.args.isCurrent)      
    }
  }
}

Apparently, DynamoDB does not let you filter on Complex object types like List of Maps (your case), see a related question: DynamoDB: How to store a list of items

I'd suggest changing your DynamoDB table data model if possible to site , address , isCurrentAddress to achieve what you are trying to do. Or you can write logic in VTL response mapping template to filter your result set based on isCurrentAddress value. Btw AppSync recently launched JavaScript resolvers , go through that and see if that helps in writing your resolver logic simpler.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM