1

I am trying to use Sails query language to query two tables, with Postgresql as the database.

I have two tables 'Person' and 'Pet'.

For 'Person', its model is:

id: { type: 'integer', primaryKey }
namePerson: { type: 'string' }
age: { type: 'integer' }

For 'Pet', its model is:

id: { type: 'integer', primaryKey }
owner: { model: 'Person' }
namePet: { type: 'string' }

I want to find all the pets who are owned by people younger than 12, and I want to do it in a single query. Is that possible?

I only know how to do it in two queries. First, find all the people who are younger than 12:

Person.find({age: {'<', 12}}).exec(function (err, persons) {..};

Then, find all the pets owned by them:

Pet.find({owner: persons}).exec( ... )
Joe Hill
  • 333
  • 3
  • 12
JustWonder
  • 2,373
  • 3
  • 25
  • 36

1 Answers1

2

You need here one-to-many association (one person can have several pets).

Your person should be associated with pets:

module.exports = {

    attributes: {
        // ...
        pets:{
            collection: 'pet',
            via: 'owner'
        }
    }
}

Your pets should be associated with person:

module.exports = {

    attributes: {
        // ...
        owner:{
            model:'person'
        }
    }
}

You can still find user by age criteria:

Person
    .find({age: {'<', 12}})
    .exec(function (err, persons) { /* ... */ });

To fetch user with his pets you should populate association:

Person
    .find({age: {'<', 12}})
    .populate('pets')
    .exec(function(err, persons) { 
        /* 
        persons is array of users with given age. 
        Each of them contains array of his pets
        */ 
    });

Sails allow you to perform multiple population in one query like:

Person
    .find({age: {'<', 12}})
    .populate('pets')
    .populate('children')
    // ...

But nested populations is not exist, issue discussion here.

Boris Zagoruiko
  • 12,705
  • 15
  • 47
  • 79
  • thanks for you answer. It explains very well. One more question. I found that the query: Person.find({age: {'<', 12}}).populate('pets') also returns persons which no pets, i.e. { ... pets: [ ] ... }. It is possible to just return persons with at least one pet? Thanks. – JustWonder Sep 28 '15 at 14:10