npm package: @geekbears/gb-mongoose-keywords-plugin
Description: A Mongoose plugin for keyword generation
Author: It Geekbears
Latest version: 1.1.32

# GB Mongoose Keywords Plugin

A Mongoose Plugin for keyword generation

## Installation

This package is available for download from the internal Geekbears NPM registry. To install it, run the following command

```bash
npm install --save @geekbears/gb-mongoose-keywords-plugin
```

## Usage

Once installed, add the plugin to your Schema definition. Pass an object with the following options to configure the behavior of keyword generation.

### Available options

-   `paths`: a collection of the local schema paths to generate keywords from. See below for more details
-   `virtuals`: a key-value map of virtual paths to be populated and generate keywords from. See below for more details.
-   `omit`: a collection of words to be omitted from the resulting keywords

### Paths

Local fields from the same schema. Supported types are string, array and object, and no additional configuration is needed since the type is detected upon generation and handled accordingly.

> **CURRENT LIMITATION:** In the case of objects, keywords will be generated from **all** properties. This will be addressed in the future

### Virtuals

The virtuals map is a key-value pair of paths to populate and fields to select from that path. Keys refer to the virtual path and the value must be an array of internal fields.

```typescript
{
    artists: ['name', 'genres'];
}
```

Both single documents as well as arrays of documents are supported, and no additional configuration is needed since the type is detected upon generation and handled accordingly.

> **CURRENT LIMITATION:** Deep virtuals are currently not supported, this means the plugin can only generate keywords from virtuals one level deep. This will be addressed in a future release

### Typescript

The `__keywords` field is added to the schema definition upon setup. However, when using classes, the field must be added manually to the class definition. The package exports the `IKeywordedDocument` interface that inherits from `Document for this purpose.

You can then define the type as follows

```typescript
import { IKeywordedDocument } from '@geekbears/gb-mongoose-keywords-plugin';

export type AlbumDocument = Album & IKeywordedDocument;
```

This will ensure the `__keywords` field is available when querying the model.

### Configuration example

Import the plugin and add it to your schema within the `MongooseModule.forFeatureAsync()` factory

```typescript
import { KeywordsMiddleware } from '@geekbears/gb-mongoose-keywords-plugin';

MongooseModule.forFeatureAsync([
    {
        name: Album.name,
        useFactory: () => {
            const schema = AlbumSchema;

            // Configure
            schema.plugin(KeywordsMiddleware, {
                paths: ['name', 'description', 'genres'],
                virtuals: {
                    artists: ['name', 'genres'],
                },
            });

            return schema;
        },
    },
]);
```

This will generate keywords from the `name`, `description` and `genres` local paths, as well as populate the `artists` path and generate keywords from the `name` and `genres` fields inside `artists`

### Query example

The purpose of generating keywords is to facilitate a search functionality. Execute a query on the `__keywords` field using a regular expression as follows, to implement a search on a given model.

```typescript
albumModel.find({ __keywords: { $elemMatch: { $regex: new Regex() } } });
```

## How does it work?

The plugin adds a new `__keywords` field to the provided schema, and sets up a text index to facilitate a search feature implementation.

Then, it automatically generates keywords from the specified local and virtual paths and persists them into said field, whenever a new document is created or an update query is issued via the `findOneAndUpdate` method.

## Troubleshooting

The plugin performs a set of validation checks during setup to mitigate possible runtime errors. Most common errors are:

### No options provided

Occurs when the options object is missing from the setup call. An options object MUST be passed to the `schema.plugin()` call. Make sure the options object is included as a second parameter in the setup call and it's not `nil`.

### Path not present in schema

Occurs when a provided local path is not defined in the schema. All local paths MUST exist in the schema. Make sure the specified local path exists in the schema and check for any naming typos.

### Virtual not present in schema

Occurs when a provided virtual path is not defined in the schema. All virtual paths MUST exist in the schema. Make sure the specified virtual path exists in the schema and check for any naming typos.

### Must provide at least one of the following options: paths, virtuals

Occurs when none of the path option fields (`paths` and `virtuals`) are included in the options object. Make sure at least one of them is specified in the options object passed to the setup call, and it's not `nil`.

## Contributing

Additional contribution is welcome. If you find a bug or have a new feature in mind, don't hesitate to create a new branch and send a new Merge Request with your changes. Make sure to follow the current Geekbears guidelines for project contribution.