构建带数组参数的Mongoose查询:查找符合需求的空位Lobby
Got it, let's break down how to build this query properly. You already have the region and language filters in place—now we just need to add conditions to check that the selected roles have vacant spots (i.e., the corresponding fields are null in the Lobby document).
Step 1: Understand the Role Vacancy Condition
Each role (guardian, support, dps) in your Schema uses null as the default when the spot is empty. So for every role the user selects, we need to ensure the matching field in the Lobby is null.
Step 2: Build Dynamic Role Conditions
Assuming the user's selected roles are stored in an array like selectedRoles (e.g., ['guardian', 'dps']), we can dynamically create the query conditions for these roles. This keeps the code flexible whether the user picks 1, 2, or 3 roles.
Step 3: Combine All Conditions
We'll merge the region, language, and role vacancy conditions into a single query. Here are two clean ways to do it:
Option 1: Object Spread for Query Object
// Assume these are user-selected values const region = "na"; const languages = ["en", "es"]; const selectedRoles = ["guardian", "support"]; // Validate roles to avoid invalid fields (optional but recommended) const validRoles = ["guardian", "support", "dps"]; const filteredRoles = selectedRoles.filter(role => validRoles.includes(role)); // Build role vacancy conditions const roleConditions = {}; filteredRoles.forEach(role => { roleConditions[role] = null; }); // Execute the query const lobby = await Lobby.findOne({ region: region, languages: { $in: languages }, // Same as .where('languages').in(languages) ...roleConditions });
Option 2: Chained Query Methods
If you prefer using Mongoose's chained method syntax:
// User-selected values const region = "na"; const languages = ["en", "es"]; const selectedRoles = ["dps"]; // Start with base filters let query = Lobby.findOne({ region: region }) .where("languages").in(languages); // Add role vacancy checks dynamically const validRoles = ["guardian", "support", "dps"]; selectedRoles.forEach(role => { if (validRoles.includes(role)) { query = query.where(role).equals(null); } }); // Run the query const lobby = await query.exec();
Key Notes
- The
validRolesfilter is optional but prevents accidental queries for fields that don't exist in your Schema (which would return no results or cause errors). - Mongoose automatically combines multiple query conditions with an
$andoperator, so all filters (region, language, role vacancies) must be satisfied for a Lobby to match. - Don't forget to use
awaitwhen executing the query (or handle promises with.then()) to get the actual document result.
内容的提问来源于stack exchange,提问作者KipIpiWow

