[英]DynamoDB Query / Scan with combined conditions
I am facing an architectural problem (or a logical one) and am not sure what is the best way to proceed. 我正面临一个体系结构问题(或合乎逻辑的问题),并且不确定最好的处理方法是什么。 I am building a small matchmaking app to study AWS Mobile HUB and it's services and get a bit more familiar with it. 我正在构建一个小型配对应用程序,以研究AWS Mobile HUB及其服务,并对它更加熟悉。
My DynamoDB contains a table with rendezvous
that have the following 2 properties (and some more which are not important here): 我的DynamoDB包含一个具有rendezvous
的表,该表具有以下2个属性(还有一些此处不重要的属性):
Rendezvous
- from_gender
- interest_gender
Additionally i am using cognito and have my users have a property 另外,我正在使用Cognito,并让我的用户拥有财产
User
- usr_gender
- interest_gender
Basically I want to match up users that are interested in from_gender
and possess a gender of interest_gender
基本上,我想匹配对from_gender
感兴趣且性别为interest_gender
At the moment, User
can be either male
or female
whereas interest_gender
can be either male
, female
or all
. 目前, User
可以是male
或female
而interest_gender
可以是male
, female
或all
。
This means for a user we have 6 combinations: 这意味着对于一个用户,我们有6种组合:
Gender -> Interested In
Male -> female
Female -> female
Female -> all
Male -> all
Male -> male
Female -> male
Now it gets tricky: 现在变得棘手:
Example 例
User A ( female
interested in all
) is looking for rendezvous
用户A(对all
感兴趣的female
)正在寻找rendezvous
She should be shown the 4 following rendezvous types: 应该为她显示以下4种会合类型:
from_gender, interest_gender
male, female
male, all
female, female
female, all
which means that I would need a query of sorts (dummycode): 这意味着我需要一个查询(dummycode):
rendevous.query(" rendevous.query(“
(from_gender = male) AND ((interest_gender = female") OR (interest_gender = all)) OR (from_gender =男性)AND((interest_gender =女性“)或(interest_gender =全部))OR
(from_gender = female) AND ((interest_gender = female") OR (interest_gender = all)) (from_gender =女性)AND((interest_gender =女性“)或(interest_gender =全部))
") ”)
However 然而
I have not yet found a way to get this working with query or scan as they do not support OR queries on the same property. 我还没有找到一种方法来处理查询或扫描,因为它们不支持对同一属性的OR查询。
I tried to create indeces (using codes for the different combinations, but i did not find a way to create a queryable index for all cases), note that additionally to this interest I would also need to sort by age (between min / max) and location min/max lat, min/max long. 我尝试创建indees(使用不同组合的代码,但没有找到为所有情况创建可查询索引的方法), 请注意 ,除此兴趣外,我还需要按年龄(最小/最大)排序和位置最小/最大纬度,最小/最大时长。
Are there any smart approaches using DynamoDB or am I forced to go the SQL route? 是否有使用DynamoDB的智能方法,还是我被迫走SQL路线?
This is the query expression I have tried latest: Works 这是我最近尝试过的查询表达式: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
}
Are you absolutely certain you can't use an OR
condition on a DynamoDB scan
operation? 您是否绝对确定不能在DynamoDB scan
操作上使用OR
条件? I'm not saying you're wrong, I just seem to remember doing it. 我并不是说您错了,我只是记得记得这么做了。 Here is some code I would try if I were working on the same issue: 如果我正在处理相同的问题,请尝试以下代码:
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
})
}
This would assume that you have your Rendezvous
object that conforms to AWSDynamoDBObjectModel
and AWSDynamoDBModeling
. 这将假定您具有符合AWSDynamoDBObjectModel
和AWSDynamoDBModeling
Rendezvous
对象。 Try it, and let me know if it works for you, otherwise I'll delete my answer. 尝试一下,让我知道它是否适合您,否则我将删除答案。 I don't have the ability to test it for you until much later tonight, so I'm not 100% certain it will work. 直到今晚晚些时候,我才有能力为您进行测试,因此我不确定100%是否可以运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.