繁体   English   中英

结合条件进行DynamoDB查询/扫描

[英]DynamoDB Query / Scan with combined conditions

我正面临一个体系结构问题(或合乎逻辑的问题),并且不确定最好的处理方法是什么。 我正在构建一个小型配对应用程序,以研究AWS Mobile HUB及其服务,并对它更加熟悉。

我的DynamoDB包含一个具有rendezvous的表,该表具有以下2个属性(还有一些此处不重要的属性):

Rendezvous

- from_gender
- interest_gender

另外,我正在使用Cognito,并让我的用户拥有财产

User

- usr_gender
- interest_gender

基本上,我想匹配对from_gender感兴趣且性别为interest_gender

目前, User可以是malefemaleinterest_gender可以是malefemaleall

这意味着对于一个用户,我们有6种组合:

Gender -> Interested In

Male -> female 
Female -> female 
Female -> all 
Male -> all 
Male -> male
Female -> male

现在变得棘手:

用户A(对all感兴趣的female )正在寻找rendezvous

应该为她显示以下4种会合类型:

from_gender, interest_gender

male, female
male, all
female, female
female, all

这意味着我需要一个查询(dummycode):

rendevous.query(“

(from_gender =男性)AND((interest_gender =女性“)或(interest_gender =全部))OR

(from_gender =女性)AND((interest_gender =女性“)或(interest_gender =全部))

”)

然而

我还没有找到一种方法来处理查询或扫描,因为它们不支持对同一属性的OR查询。

我尝试创建indees(使用不同组合的代码,但没有找到为所有情况创建可查询索引的方法), 请注意 ,除此兴趣外,我还需要按年龄(最小/最大)排序和位置最小/最大纬度,最小/最大时长。

是否有使用DynamoDB的智能方法,还是我被迫走SQL路线?

这是我最近尝试过的查询表达式:Works

func generateScanExpression() -> AWSDynamoDBScanExpression {
    let usr = UserHelper.sharedHelper.currentUser
    let expression = AWSDynamoDBScanExpression()
    expression.limit = 10

    // Male interested in male
    if (usr?.interest == Constants.CONST_MALE) && (usr?.gender == Constants.CONST_MALE){
        expression.filterExpression = "details_fromGender = :fg AND ( match_interest = :ig OR match_interest = :all )"
        expression.expressionAttributeValues = [":fg": Constants.CONST_MALE, ":ig": Constants.CONST_MALE, ":all": Constants.CONST_ALL ]
    }
    // Female interested in female
    if (usr?.interest == Constants.CONST_FEMALE) && (usr?.gender == Constants.CONST_FEMALE){
        expression.filterExpression = "details_fromGender = :fg AND ( match_interest = :ig OR match_interest = :all )"
        expression.expressionAttributeValues = [":fg": Constants.CONST_FEMALE, ":ig": Constants.CONST_FEMALE, ":all": Constants.CONST_ALL ]
    }
    // Male interested in female
    if (usr?.interest == Constants.CONST_FEMALE) && (usr?.gender == Constants.CONST_MALE){
        expression.filterExpression = "details_fromGender = :fg AND ( match_interest = :ig OR match_interest = :all )"
        expression.expressionAttributeValues = [":fg": Constants.CONST_FEMALE, ":ig": Constants.CONST_MALE, ":all": Constants.CONST_ALL ]
    }
    // Female interested in male
    if (usr?.interest == Constants.CONST_MALE) && (usr?.gender == Constants.CONST_FEMALE){
        expression.filterExpression = "details_fromGender = :fg AND ( match_interest = :ig OR match_interest = :all )"
        expression.expressionAttributeValues = [":fg": Constants.CONST_MALE, ":ig": Constants.CONST_FEMALE, ":all": Constants.CONST_ALL ]
    }
    // Male interested in all
    if (usr?.interest == Constants.CONST_ALL) && (usr?.gender == Constants.CONST_MALE){
        expression.filterExpression = "( details_fromGender = :fg OR details_fromGender = :all ) AND match_interest = :ig"
        expression.expressionAttributeValues = [":fg": Constants.CONST_MALE, ":ig": Constants.CONST_MALE ]
    }
    // Female interested in all
    if (usr?.interest == Constants.CONST_ALL) && (usr?.gender == Constants.CONST_FEMALE){
        expression.filterExpression = "( details_fromGender = :fg OR details_fromGender = :all ) AND match_interest = :ig"
        expression.expressionAttributeValues = [":fg": Constants.CONST_MALE, ":ig": Constants.CONST_FEMALE ]
    }

    return expression
}

您是否绝对确定不能在DynamoDB scan操作上使用OR条件? 我并不是说您错了,我只是记得记得这么做了。 如果我正在处理相同的问题,请尝试以下代码:

func findMatches(interestGender: String, userGender: String, allCondition: String, map: AWSDynamoDBObjectMapper) -> AWSTask<AnyObject> {
    let scan = AWSDynamoDBScanExpression()
    scan.filterExpression = "interest_gender = :interestGender AND usr_gender = :userGender OR interest_gender = :allCondition"
    scan.expressionAttributeValues = [":interest_gender":interestGender, ":usr_gender":userGender, ":interest_gender":allCondition]

    return map.scan(Rendezvous.self, expression: scan).continue({ (task: AWSTask) -> AnyObject? in
        if (task.error != nil) {
            print(task.error)
        }

        if (task.exception != nil){
            print(task.exception)
        }

        if let result = task.result {
            return result.items as! [Rendezvous] as AnyObject?
        }

        return nil
    })

}

这将假定您具有符合AWSDynamoDBObjectModelAWSDynamoDBModeling Rendezvous对象。 尝试一下,让我知道它是否适合您,否则我将删除答案。 直到今晚晚些时候,我才有能力为您进行测试,因此我不确定100%是否可以运行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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