Garrett
Garrett

Reputation: 709

Using results from one RethinkDB query in another?

I want to send a http post with an address, which will grab a doc from the database. I would like to then use that doc's geodata in a getNearest function, ultimately returning the nearest four other locations. How do I go about stringing these two queries together?

r.table('dealer_locations').filter(function(dealer) {
return {
      dealer :  ("Address").match(request.body.Address)
      .getNearest(dealer, {
            index: 'geodata',
            maxResults: 4
          })
      }
    }).run(conn, function(error, cursor) {
      if (error) {
        handleError(response, error);
      } else {
        cursor.toArray(function(error, results) {
          if (error) {
            handleError(response, error);
          } else {
            response.send(results);
          }
        });
      }
    });

Upvotes: 2

Views: 211

Answers (1)

Jorge Silva
Jorge Silva

Reputation: 4614

I'll reformulate the question just to make a bit more clear:

Problem

Given a specific document with geodata, I want to also return the four nearest locations to that location.

Solution

First, make sure that you've creating the geo index in the table you want to query:

r.table('dealer_locations').indexCreate('location', { geo: true })

After that, make sure that you've inserted a r.point object into the document. You can't just use geo indexes on just any property. They have to be r.points.

r.table('dealer_locations')
  .insert({
    name: 'San Francisco', 
    location: r.point(37.774929, -122.419416)
  })

After you've inserted all your documents and they all have r.points property on the same property you created an index for, now you can start querying them.

If you want to get all the nearest locations for a location, you can do as follows:

r.table('dealer_locations')
 .filter({ name: 'San Francisco' })(0)
 .do(function (row) {
   return r.table('dealer_locations')
     .getNearest(row('location'), { index: 'location', maxResults: 4 })
 })

If you want to append the closets locations to a document, so that you can return both the document and the nearest locations at the same time, you can do that using the merge method.

r.table('dealer_locations')
 .filter({ name: 'San Francisco' })(0)
 .merge(function (row) {
   return {
     nearest_locations: r.table('dealer_locations')
       .getNearest(row('location'), { index: 'location', maxResults: 4 })
   }
 })

Finally, if you want to get all the nearest locations, based on an address (supposing your document has both an address property with a string and a location property with an r.point), you can do something like this:

r.table('dealer_locations')
 .filter(r.row('address').match(request.body.Address))
 (0) // Only get the first document
 .do(function (row) {
   // Return the 4 documents closest to the 'location' if the previous document
   return r.table('dealer_locations')
     .getNearest(row('location'), { index: 'location', maxResults: 4 })
 })

That being said, the problem with this might be that you might match multiple addresses which are not necessarily the ones you want to match!

Upvotes: 3

Related Questions