阿里云主机折上折
  • 微信号
Current Site:Index > Conditional queries and complex filtering

Conditional queries and complex filtering

Author:Chuan Chen 阅读数:58611人阅读 分类: MongoDB

Basic Conditional Queries

Mongoose provides a variety of query methods, with the most basic being the find() method. It accepts a condition object as a parameter and returns all documents that match the condition.

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

// Find all users older than 18
User.find({ age: { $gt: 18 } })
  .then(users => console.log(users))
  .catch(err => console.error(err));

Common comparison operators include:

  • $eq: Equal to
  • $ne: Not equal to
  • $gt: Greater than
  • $gte: Greater than or equal to
  • $lt: Less than
  • $lte: Less than or equal to
  • $in: In an array
  • $nin: Not in an array

Logical Operators for Combined Queries

Mongoose supports using logical operators to combine multiple conditions for more complex query logic.

// Find users aged between 18 and 30 or named "Zhang San"
User.find({
  $or: [
    { age: { $gte: 18, $lte: 30 } },
    { name: 'Zhang San' }
  ]
}).exec();

Main logical operators:

  • $and: Logical AND
  • $or: Logical OR
  • $nor: Logical NOR
  • $not: Logical NOT

Array Condition Queries

When querying fields that contain arrays, Mongoose provides specialized operators for array queries.

const Post = mongoose.model('Post', postSchema);

// Find articles tagged with "Technology"
Post.find({ tags: 'Technology' }).exec();

// Find articles tagged with both "Technology" and "Programming"
Post.find({ tags: { $all: ['Technology', 'Programming'] } }).exec();

// Find articles with exactly 3 tags
Post.find({ tags: { $size: 3 } }).exec();

Array-specific operators:

  • $all: Contains all specified elements
  • $elemMatch: Array elements match all conditions
  • $size: Array length matches

Nested Document Queries

For nested documents or object-type fields, dot notation can be used for queries.

const Order = mongoose.model('Order', orderSchema);

// Find orders with shipping address city as "Beijing"
Order.find({ 'shipping.address.city': 'Beijing' }).exec();

// Use $elemMatch to query nested arrays
Order.find({
  items: {
    $elemMatch: {
      product: 'Phone',
      quantity: { $gte: 2 }
    }
  }
}).exec();

Regular Expression Queries

Mongoose supports regular expressions for fuzzy queries, especially useful for text searches.

// Find users whose names start with "Zhang"
User.find({ name: /^Zhang/ }).exec();

// Use RegExp object, case-insensitive
User.find({ name: new RegExp('wang', 'i') }).exec();

Pagination and Sorting

Combined with conditional queries, pagination and sorting are often needed.

const page = 1;
const limit = 10;

User.find({ active: true })
  .sort({ createdAt: -1 }) // Sort by creation time in descending order
  .skip((page - 1) * limit) // Skip previous records
  .limit(limit) // Limit the number of returned results
  .exec();

Aggregation Queries

For more complex data analysis and statistics, Mongoose's aggregation framework can be used.

User.aggregate([
  { $match: { age: { $gte: 18 } } }, // Conditional filtering
  { $group: { 
    _id: '$city', 
    total: { $sum: 1 },
    avgAge: { $avg: '$age' }
  } }, // Group by city and calculate statistics
  { $sort: { total: -1 } }, // Sort by total in descending order
  { $limit: 5 } // Return only the top 5
]).exec();

Query Performance Optimization

For large datasets, query performance optimization is crucial.

  1. Index Optimization:
userSchema.index({ name: 1 }); // Single-field index
userSchema.index({ age: 1, city: 1 }); // Compound index
  1. Selective Queries: Query only the required fields
User.find({}, 'name email').exec(); // Return only name and email fields
  1. Use lean(): Return plain JS objects instead of Mongoose documents to reduce overhead
User.find().lean().exec();

Chained Query Building

Mongoose queries support chaining, allowing dynamic construction of query conditions.

const query = User.find();

// Dynamically add query conditions
if (minAge) {
  query.where('age').gte(minAge);
}
if (maxAge) {
  query.where('age').lte(maxAge);
}
if (namePattern) {
  query.where('name').regex(new RegExp(namePattern, 'i'));
}

query.exec().then(users => {
  // Process results
});

Advanced Query Techniques

  1. Using $where: Execute JavaScript expressions
User.find({ $where: 'this.age > this.minAge + 5' }).exec();
  1. Geospatial Queries: For data containing geographic coordinates
const Place = mongoose.model('Place', placeSchema);

Place.find({
  location: {
    $near: {
      $geometry: {
        type: 'Point',
        coordinates: [longitude, latitude]
      },
      $maxDistance: 1000 // Within 1 km
    }
  }
}).exec();
  1. Text Search: Requires creating a text index first
postSchema.index({ content: 'text' });

Post.find({ $text: { $search: 'database optimization' } })
  .sort({ score: { $meta: 'textScore' } })
  .exec();

本站部分内容来自互联网,一切版权均归源网站或源作者所有。

如果侵犯了你的权益请来信告知我们删除。邮箱:cc@cccx.cn

Front End Chuan

Front End Chuan, Chen Chuan's Code Teahouse 🍵, specializing in exorcising all kinds of stubborn bugs 💻. Daily serving baldness-warning-level development insights 🛠️, with a bonus of one-liners that'll make you laugh for ten years 🐟. Occasionally drops pixel-perfect romance brewed in a coffee cup ☕.