You can use the ANY operator to test whether any item in an array meets a condition. In this case you’d need two of those, one to look for each string.
The Problem is, that the number of languages in the database may have up to 25 entries. Also the number of items to query for is variable. It may be only 1 or it may be 15. How to put that into code?
I tried this: var valueExpressions: [ExpressionProtocol] = [ExpressionProtocol]() for lang in languages { valueExpressions.append(Expression.string(lang)) }
OK, I figured out how to do it. For anybody who is interested:
func getIdsByPropertyArray(_ property:String, values:[String]) -> Set<String> {
var matchingIds = Set<String>()
var whereExpr:ExpressionProtocol = ArrayFunction.contains(Expression.property(property), value:Expression.string(values[0]))
for i in 1..<values.count {
whereExpr=whereExpr.or(ArrayFunction.contains(Expression.property(property), value: Expression.string(values[i])))
}
let query = QueryBuilder
.select(
SelectResult.expression(Meta.id)
)
.from(DataSource.database(database))
.where(whereExpr)
do {
for result in try query.execute() {
matchingIds.insert(result.string(forKey: "id")!)
}
} catch let error {
print(error.localizedDescription)
}
return matchingIds
}
It works, but: it is extremely slow! It takes about 4 seconds with a dataset of 1.000 documents. Now I get all documents from the database and sort out the ones I need with reduce. This only takes about 0.002 seconds …