als-mongo-list v2.4.0
als-mongo-list
als-mongo-list is a Node.js library designed to help you quickly build search, filter, sort, and pagination logic for Mongoose-based MongoDB queries. It simplifies building complex query interfaces by providing a structured way to:
- Filter documents by various fields, including support for ranges, enums, dates, booleans, ObjectIds, and array fields.
- Search text fields using regular expressions with enhanced configuration options.
- Sort by specified keys, including strings, numbers, booleans, and dates.
- Paginate results efficiently, including total count and navigation controls.
- Dynamically generate input fields for building UI filters and sorting selectors.
ChangeLog for Version 2.2.0
Added Features:
- Boolean Fields Input Update:
- Boolean fields now use a
<select>input instead of a<input type="checkbox">. - Added an additional option "all" to include both true and false results (by default).
- Boolean fields now use a
- Improved Search Logic:
- If only one searchable field is configured, the search applies directly to that field.
- If multiple searchable fields are configured:
- A search input (type="search") is generated for the query text.
- Corresponding checkbox inputs for each field are provided to enable or disable specific fields in the search query.
- Array Field Filtering:
- Added support for filtering array fields within documents.
- The library now generates filters for array fields, allowing regex-based or equality-based filtering.
- For
searchIn,orderBy,populate,selectif key not in model's tree, console.warn will warn for it
Installation
Install via npm:
npm install als-mongo-listUsage
First, define your Mongoose model and schema as usual:
const mongoose = require("mongoose");
const userSchema = new mongoose.Schema({
name: { type: String },
age: { type: Number, min: 18, max: 99 },
isActive: { type: Boolean },
userId: { type: mongoose.Types.ObjectId },
createdAt: { type: Date, default: Date.now },
status: { type: String, enum: ["active", "inactive", "pending"] },
tags: [{ type: String }], // Example array field
});
const UserModel = mongoose.model("User", userSchema);Then, initialize als-mongo-list with your model:
const List = require("als-mongo-list");
const list = new List(UserModel)
.searchIn("name", "tags") // Fields to include in search/filter.
.orderBy("age") // Fields allowed for sorting.
.populate("userId") // Fields to populate.
.select("name", "age", "status"); // Fields to select.Executing Queries
Once configured, you can execute queries by passing in query parameters and, optionally, an initial search object. Query parameters may include filters (e.g., age_gte, age_lte), sorting (orderBy), pagination (currentPage, pageSize), and full-text search (search).
Example:
(async () => {
const query = {
search: "John",
age_gte: "25",
orderBy: "age",
currentPage: "0",
pageSize: "10",
};
const result = await list.exec(query, { userId: "someuserid" });
if (result.error) {
console.error("Query error:", result.error);
} else {
console.log(result.items); // Paginated array of documents
console.log(result.total); // Total number of documents matching the filters
console.log(result.inputs); // Input definitions for building a UI
console.log(result.query); // Query parameters (with normalized pagination)
}
})();Updated Features
Boolean Fields
- New Input Type:
Booleanfields now use a<select>with the following options:"all": No filtering (default)."true": Includes documents where the field istrue."false": Includes documents where the field isfalse.
Example Input Definition:
{
"isActive": {
"tag": "select",
"name": "isActive",
"options": [
{ "value": "", "text": "all" },
{ "value": "true", "text": "true" },
{ "value": "false", "text": "false" }
]
}
}Enhanced Search Logic
Single Search Field:
- If only one field is included in the search configuration, the query applies directly to that field without
$or.
- If only one field is included in the search configuration, the query applies directly to that field without
Multiple Search Fields:
- If multiple fields are configured, a
searchinput is generated alongside checkboxes for each field. Users can enable or disable specific fields for inclusion in the search query.
- If multiple fields are configured, a
Example Input Definition:
{
"search": {
"tag": "input",
"type": "search",
"name": "search",
"keys": [
{ "tag": "input", "type": "checkbox", "name": "name", "checked": true },
{ "tag": "input", "type": "checkbox", "name": "tags", "checked": true }
]
}
}Array Field Filtering
- Array fields are now supported for filtering. You can search for documents where any element in the array matches a given value (or regex).
Example: Given a schema with an array field:
tags: [{ type: String }];You can perform a search:
const query = { tags: "technology" };
const result = await list.exec(query);The library will filter documents where the tags array contains "technology".
Dynamic Input Definitions
als-mongo-list generates metadata (inputs) about possible filters and sorts. These can be used to build dynamic UIs. For example, result.inputs.filter and result.inputs.sort provide configuration for creating input elements (like <input>, <select>, etc.) that match the filter and sort capabilities of the current configuration.
Updated Example: Boolean, search, and array fields are now supported dynamically:
// Suppose `list.exec(query)` returns `result.inputs` as follows:
console.log(result.inputs);
/*
{
filter: {
search: {
tag: 'input',
type: 'search',
name: 'search',
keys: [
{ tag: 'input', type: 'checkbox', name: 'name', checked: true },
{ tag: 'input', type: 'checkbox', name: 'tags', checked: true }
]
},
isActive: {
tag: 'select',
name: 'isActive',
options: [
{ value: "", text: "all" },
{ value: "true", text: "true" },
{ value: "false", text: "false" }
]
},
tags: { tag: 'input', type: 'search', name: 'tags' },
age_gte: { tag: 'input', type: 'number', name: 'age_gte', min: 18, max: 99 },
age_lte: { tag: 'input', type: 'number', name: 'age_lte', min: 18, max: 99 },
},
sort: {
tag: 'select',
name: 'orderBy',
options: [
{ value: '-age', text: 'small_big', key: 'age' },
{ value: 'age', text: 'big_small', key: 'age' },
// ... other sort options
]
},
pagination: { /* pagination info from als-pagination *-/ }
}
*/