Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
907 views
in Technique[技术] by (71.8m points)

node.js - Node - Mongoose 3.6 - Sort query with populated field

I am trying to do a query used by a remote grid, so I will have to handle sort (asc, desc) on every fields.

Here are the schemas:

var customerSchema = new mongoose.Schema({
status: {type: mongoose.Schema.Types.ObjectId, ref: 'Status'},
contact: {type: mongoose.Schema.Types.ObjectId, ref: 'Contact'}
}, { collection: 'Customer' });

customerSchema.virtual('contactName').get(function () {
   if (this.contact && this.contact.get) {
       return this.contact.get('firstName') + ' ' + this.contact.get('lastName');
   }

   return '';
});

customerSchema.virtual('statusName').get(function () {
   if (this.status && this.status.get) {
       return this.status.get('name');
   }

   return '';
});

customerSchema.set('toJSON', { virtuals: true });
customerSchema.set('toObject', { virtuals: true });
mongoose.model('Customer', customerSchema);

// STATUS
var statusSchema = new mongoose.Schema({}, { collection: 'Status' });
mongoose.model('Status', statusSchema);

// CONTACT
var contactSchema = new mongoose.Schema({
    firstName: String,
    lastName: String
}, { collection: 'Contact' });
mongoose.model('Contact', contactSchema);

And here is the query:

exports.customerList = function (predicate ,callback){
if (!predicate) predicate = 'name';
var Customers = mongoose.model( 'Customer' );
    
Customers.find()
    .select('name phone address status contact contactName statusName')
    .populate('status', 'name')
    .populate('contact', 'firstName lastName')
    .sort(predicate)
    .exec(callback);
};

The query is working when sorting on 'name' (so Customer.name) or 'address' (Customer.address) but can't get it to work when it is 'contact.firstName' (should be Customer.contact.firstName).

The fourth parameters of the populate function is an option object which can have a sort object, but doing this:

.populate('contact', 'firstName lastName', null, { sort {'firstName': 1}})

is not working (seem to sort contact list on customer).

I am completely new to mongoose (and mongo). I am trying to port a rails projects to node/express.

Is there a way I can sort my query by contact.firstName?


Edit: I ended up doing my sort manually (Array.sort) but I really don't like this solution. Sort is sync so it block node.js main thread (correct me if I'm wrong).

Is there something I don't understand? Sorting dataset is for me a database concern and not application... I was getting lot of hope about turning my rails application into node.js but it seem that some standard operation (paging a grid) are really hard to implement!

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

You can't sort on virtual fields or populated fields as those fields are only present in your app objects (Mongoose model instances) but the sort is executed within MongoDB.

This is one of the key limitations that results from MongoDB not supporting joins. If your data is highly relational then you should consider using a relational database instead of MongoDB.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...