havak5
havak5

Reputation: 724

How to perform DynamoDB scan using filterExpression in swift

I have a table that stores information about groups (GroupID, Members, Creator, LastAccessed, GroupName, etc..) as separate rows. Each group has a unique identifier (GroupID) as their hash (primary key). They also have an attribute called GroupName. I have a search box where the user inputs a partial group name. I want to perform a scan on the table and return all of the groups that begin with the users input. Here is what I have so far..

func searchForGroupsWithName(groupName: String) {

    self.queryInProgress = true

    let cond = AWSDynamoDBCondition()
    let v1    = AWSDynamoDBAttributeValue();
    v1.S = groupName

    cond.comparisonOperator = AWSDynamoDBComparisonOperator.BeginsWith
    cond.attributeValueList = [ v1 ]

    let exp = AWSDynamoDBScanExpression()

    //I only want to return the GroupName and GroupID.
    //I think this should be ["GroupID", "GroupName"], but it requires a string
    exp.projectionExpression = ??????????

    //I am not sure how to incorporate cond with this.
    exp.filterExpression = ??????????

    dynamoDBObjectMapper.scan(GroupTableRow.self, expression: exp).continueWithBlock({ (task:AWSTask!) -> AnyObject! in

        if task.result != nil {
            let paginatedOutput = task.result as! AWSDynamoDBPaginatedOutput

            for item in paginatedOutput.items as! [GroupTableRow] {
                self.searchBarResults.append(item)
            }

            if ((task.error) != nil) {
                print("Error: \(task.error)")
            }
            self.queryInProgress = false
            return nil
        }
        self.queryInProgress = false
        return nil
    })
}

Upvotes: 2

Views: 1623

Answers (2)

havak5
havak5

Reputation: 724

After getting help from WestonE, I fixed up my code and have a working example. I have pasted it below for anyone else who needs something similar

func searchForGroupsWithName(groupName: String) {

    self.queryInProgress = true

    let lowercaseGroupName = groupName.lowercaseString

    let scanExpression = AWSDynamoDBScanExpression()

    //Specify we want to only return groups whose name contains our search
    scanExpression.filterExpression = "contains(LowercaseName, :LowercaseGroupName)"

    //Create a scan expression to state what attributes we want to return
    scanExpression.projectionExpression = "GroupID, GroupName, LowercaseName"

    //Define our variable in the filter expression as our lowercased user input
    scanExpression.expressionAttributeValues = [":LowercaseGroupName" : lowercaseGroupName]

    dynamoDBObjectMapper.scan(GroupTableRow.self, expression: scanExpression).continueWithBlock({ (task:AWSTask!) -> AnyObject! in

        if task.result != nil {
            let paginatedOutput = task.result as! AWSDynamoDBPaginatedOutput

            //use the results
            for item in paginatedOutput.items as! [GroupTableRow] {

            }

            if ((task.error) != nil) {
                print("Error: \(task.error)")
            }
            self.queryInProgress = false
            return nil

        }

        self.queryInProgress = false
        return nil
        })
}

Upvotes: 4

WestonE
WestonE

Reputation: 702

The projectionExpression should be a single comma delimited string ["GroupID", "GroupName"] => "GroupID, GroupName"

The filterExpression is also a string, and it's documentation is http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/QueryAndScan.html#FilteringResults . In your case I think the expression would be "begins_with(groupName, BeginningCharacters)" But you might need to experiment with this.

Upvotes: 2

Related Questions