0

I am currently trying to use Firebase, Flashlight and Swift to create an search function to retrieve a random object from my realtime database.

I am trying to perform the following query to Firebase at /search/request

var searchSettings : [Any] = []

    if Settings.searchPackage != 99 {
        searchSettings.append(["match" : Settings.searchPackage])
    }

    if Settings.searchCountry != .world {
        if let region = Locale.current.regionCode {
            searchSettings.append(["match" : region])
        }
    }

    if Settings.searchGender != .All {
        searchSettings.append(["match" : Settings.searchGender.rawValue])
    }

    let postData = [
        "index" : "firebase",
        "type" : "test",
        "body" : [
            "query" : searchSettings
        ]
    ] as [String : Any]

    ref.setValue(postData, withCompletionBlock: { (error, reference) in
        if error == nil {
            FIRDatabase.database().reference().child("search/response").child(ref.key).observeSingleEvent(of: .childAdded, with: { (snapshot) in

                if snapshot.exists() {
                    print("found random snapshot based on settings \(snapshot)")
                }
            })
        }

    })

The problem is, as Firebase described in the documentation it does currently support Arrays, therefor the content of "query" will be:

Flashlight will throw an error because it expects the "query" to contain "match" fields and not the indexes of an array of them.

How would I fix this? I want to be able to search based on multiple fields.

Frank van Puffelen
  • 565,676
  • 79
  • 828
  • 807
Mads Odgaard
  • 33
  • 2
  • 7
  • Usually when you have an array and want to do a "contains" operation on it, you should actually be using a set. See [my answer here](http://stackoverflow.com/questions/40656589/firebase-query-if-child-of-child-contains-a-value), which also explains why you should pull these categories to a top-level list. – Frank van Puffelen Dec 19 '16 at 15:45
  • Since Flashlight is simply passing that query on to ES, it's ES that's complaining about the format. I'm not an ES syntax expert, but I haven't seen a query in that structure before. How did you verify that it works as you've written it here in ES? [Here's what I see for multiple field matches](https://www.elastic.co/guide/en/elasticsearch/reference/2.3/query-dsl-multi-match-query.html – Kato Dec 19 '16 at 22:30

2 Answers2

0

Technically, Flashlight doesn't care at all what you put inside the body tag; it simply passes it on to ElasticSearch. So if there is an error generated about the format, it's ElasticSearch that's doing the complaining.

What you're probably running into here is either a) ElasticSearch doesn't like that syntax, or Firebase's array-like behaviors are converting the array to an object.

Note that Flashlight will allow you to pass a JSON string in place of body. So if this is a result of the array-like behaviors, you can JSON.stringify() the query before passing it into ES, and it will come out the other end as intended.

If the problem is the ES syntax (as it appears to me) then you can simply run the queries directly against ES until they work, and then modify your client to submit correct syntax accordingly.

Kato
  • 40,352
  • 6
  • 119
  • 149
0

Take a look at this gist: BodyQuery in Swift

I wrote this in my Android application project and I'm using this to build queries for ES. Here is equivalent in Java for Android ElasticSearch needs a json query, and you can create it easily using Maps (Android)/Dictionaries (iOS). Enjoy :)

Skye
  • 1,469
  • 3
  • 14
  • 25