1
votes

I've integrated Flashlight with my Angular 2 project. Flashlight does the following:

  1. Automatically indexes specified Firebase paths to an ElasticSearch cluster and monitors those paths for changes, re-indexing any changes.
  2. Responds to query objects written to a specified Firebase path (e.g., 'search/request'), writing ElasticSearch responses to a specified Firebase path (e.g., 'search/response').

Responses are written to Firebase with the following structure:

enter image description here

Using Angularfire 2, this is what my search looks like:

searchThreads(term: string) {
    let queryBody: Object = {
        index: 'firebase',
        type: 'thread',
        q: term
    }
    this.requestKey = this.af.database.list('/search/request').push(queryBody).key
}

if I want the raw results of that search with all paths shown in the image above, I'd do something like this:

this.af.database.list(`search/response/${this.requestKey}`)

What I want is the objects found at _source. I want to iterate over the response hits and populate my view with those objects. How can I get just these objects into an observable array?

1

1 Answers

1
votes

I don't believe it's possible to extract only the _source children. However, you could make it more efficient than extracting the complete search response.

Each hit contains little information additional to the source, so just retrieve the hits and map each hit to its _source.

this.af.database
  .list(`search/response/${this.requestKey}/hits/hits`)
  .map(hits => hits.map(hit => hit._source))

Also, you could use a limit query to extract a subset of hits:

this.af.database
  .list(`search/response/${this.requestKey}/hits/hits`, {
    query: {
      limitToFirst: 10
    }
  })
  .map(hits => hits.map(hit => hit._source))

Or, if you have some criteria for a minimum score, you could perform a query after ordering by child:

this.af.database
  .list(`search/response/${this.requestKey}/hits/hits`, {
    query: {
      orderByChild: '_score',
      startAt: 1.0
    }
  })
  .map(hits => hits.map(hit => hit._source))

(I've not used Flashlight, so I'm not sure how the scoring works, but some combination of startAt and/or endAt should let you refine your query.)