Query an array with an array of values

I have data items like this:

{
mydata:
[
{
title: "item 1",
languages: ["en", "fr", "it", "pl"]
},
{
title: "item 2",
languages: ["fr", "es", "pt"]
},
{
title: "item 3",
languages: ["en", "it"]
}
]
}

How can I query for items in an array like [“en”, “it”]? It should match all data elements that contain either “en”, “it” or both in languages?

Thank you very much for your help.

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))
}

But it does not work.

The solution must be something like this:

.select(SelectResult.expression(Meta.id)) .from(DataSource.database(db)) .where(ArrayFunction.contains(Expression.property("languages"), value: Expression.string("en"))) .or(Expression.propertyArrayFunction.contains(Expression.property("languages"), value: Expression.string("it")))

But how can I have an arbitrary number of “or” clauses?

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 …