简体   繁体   中英

How we can perform sort on ObjectId column in mongodb using mongoose with expressjs-nodejs?

We are struct at one mongodb point which I would like to describe here.

We are using mongoose 5.4 and create a model like below :

var userSchema = mongoose.Schema({  
id:{ type: Number, default: 1 },
first_name: String,
last_name: String,
mail: String,
password: String,
dob: { type: String, default: '' },
gender: { type: String, default: '' },
profile_photo: { type: String, default: '' },
ethnicity: { type: String, default: '' },
contact_number: { type: String, default: '' },
user_type: Number,
address1: { type: String, default: '' },
address2: { type: String, default: '' },
area: { type: String, default: '' },
city: { type: String, default: '' },
country: { type: String, default: '' },
postcode: { type: String, default: '' },
business_name: { type: String, default: '' }, 
ip_address: String,
status: Number,
tag_line: { type: String, default: '' },
is_influencer: Number,  
wallet_id: String,
token_balance: { type: Number, default: 0 },
point_balance: { type: Number, default: 0 },
badges: [String],
membership: { type: Schema.Types.ObjectId, ref: 'Membership' }, 
transaction: [{ type: Schema.Types.ObjectId, ref: 'Transaction' }], 
property: [{ type: Schema.Types.ObjectId, ref: 'Property' }],   
reviews: [{ type: Schema.Types.ObjectId, ref: 'Review' }],
created_date: String,
});

var User = mongoose.model('User', userSchema);

var propertySchema = mongoose.Schema({
id: Number,
property_name: String,
address1: String,
area: String,
post_code: String,
category: [{ type: Schema.Types.ObjectId, ref: 'Category' }], 
category_id: [Number],
property_desc: String,
property_images: String,
slug : String,
user_id: Number,
business_key: String,
user: { type: Schema.Types.ObjectId, ref: 'User' },
reviews: [{ type: Schema.Types.ObjectId, ref: 'Review' }],
status: Number,
is_claimed: Number,
created_date: String,
});

var Property = mongoose.model('Property', propertySchema);

var categorySchema = mongoose.Schema({  
id: Number,
category_name: String,
status: Number,
user: { type: Schema.Types.ObjectId, ref: 'User' },
property: [{ type: Schema.Types.ObjectId, ref: 'Property' }],   
created_date: String,
updated_date: String    
});

var Category = mongoose.model('Category', categorySchema);

we are also using async-await for this project. we are fetching locations using below method to get location data as well User and Category.

sortClause = {};
sortClause.user=parseInt(-1);
let properties = await Property.find({'status':{$in:[1,2]}}).populate({path: 'user',
  model: 'User',select: 'first_name last_name mail contact_number'}).populate({path: 'category',
  model: 'Category',select: 'category_name id'}).sort(sortClause).skip(skip).limit(perpage).exec();

so when we get data in properties object after the execution of above line we are getting properties but as we are sorting by user's column of property model it does fetch data properly. It sorts on objectID and we would like to fetch on user's first_name.

I have tried by specifing `{'user.first_name':-1} in sort order but it doesn't work at all.

When we sort on string or Number column it works fine, but here my expected result will be bit different, Here we would like apply sort on user.first_name (Here in above example user is the ObjectId column which populate Users data and I would like to sort on first_name column of user) How can we get properties based on user's first_name column? Is there any suggestion for this problem.

You can try below aggregation from mongodb 3.6 and above

Property.aggregate([
  { "$match": { "status": { "$in": status }} },
  { "$lookup": {
    "from": "users",
    "let": { "user": "$user" },
    "pipeline": [
      { "$match": { "$expr": { "$eq": [ "$_id", "$$user" ] } } },
      { "$project": { "first_name": 1, "last_name": 1, "mail": 1, "contact_number": 1 }}
    ],
    "as": "user"
  }},
  { "$lookup": {
    "from": "categories",
    "let": { "category": "$category" },
    "pipeline": [
      { "$match": { "$expr": { "$in": [ "$_id", "$$category" ] } } },
      { "$project": { "category_name": 1, "id": 1 }}
    ],
    "as": "category"
  }},
  { "$unwind": "user" },
  { "$sort": { "user.first_name": -1 }},
  { "$skip": skip },
  { "$limit": perpage }
])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM