2.4.0 • Published 6 months ago

als-mongo-list v2.4.0

Weekly downloads
-
License
MIT
Repository
-
Last release
6 months ago

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:

  1. 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).
  2. 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.
  3. 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.
  4. 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 is true.
    • "false": Includes documents where the field is false.

Example Input Definition:

{
  "isActive": {
    "tag": "select",
    "name": "isActive",
    "options": [
      { "value": "", "text": "all" },
      { "value": "true", "text": "true" },
      { "value": "false", "text": "false" }
    ]
  }
}

Enhanced Search Logic

  1. Single Search Field:

    • If only one field is included in the search configuration, the query applies directly to that field without $or.
  2. 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.

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 *-/ }
}
*/