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
,select
if key not in model's tree, console.warn will warn for it
Installation
Install via npm:
npm install als-mongo-list
Usage
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:
Boolean
fields 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
search
input 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 *-/ }
}
*/