Novelty Promotes Magicians

    @herbsjs/herbs2mongo

    3.0.2 • Public • Published

    CI codecov

    herbs2mongo

    herbs2mongo creates repositories to retrieve and store Entities using MongoDB.

    Installing

        $ npm install @herbsjs/herbs2mongo
    

    Using

    connection.js - MongoDB initialization:

    const {MongoClient,Logger} = require('mongodb')
    const config = require('./config')
    
    let dbInstance = null
    
    module.exports = async () => {
      if (dbInstance) {
          return new Promise((resolve) => resolve(dbInstance))
      }
      const client = await new MongoClient(config.connectionString).connect()
      dbInstance = client.db(config.databaseName)
      Logger.setLevel("debug") // set this if you want to debug all queries
      return dbInstance
    }

    itemRepository.js:

    const { Repository } = require('@herbsjs/herbs2mongo')
    const connection = require('connection')
    const { Item } = require('../domain/entities/item')
    const database = 'herbs2mongo_testdb'
    
    class ItemRepository extends Repository {
        constructor() {
            super({
                entity: Item,
                collection: 'aCollection',
                database,
                ids: ['id'],
                mongodb: connection
            })
        }
    
        excludedItemFromLastWeek() {
            ...
        }
    }

    someUsecase.js:

    const repo = new ItemRepository()
    const ret = await repo.findByID('60edc25fc39277307ca9a7ff') // note that the id is equivalent to ObjectId _id field

    What is a Repository?

    A repository, by definition, is part of the layer to retrieve and store entities abstracting the underlying implementation. By using repositories, details of these implementation such as relational database, document-oriented databases, etc, should not leak to the domain code. In other words, no raw SQL queries on your use case or entity files.

    herbs2Mongo Repository

    In order to boost productivity herbs2Mongo provides way to dynamically generate a repository class based on your Entities and other metadata.

    These metadata are necessary to close the gap between OOP concepts and paradigms and those of relational databases. For example, it is necessary to specify primary keys and foreign keys as these information do not exist in the description of your domain.

    Following Herbs architecture principals it is not the intention of this lib to create yet another ODM or query builder but to create a bridge between your domain and an existing one (from Mongo).

    Why Mongo oficial Driver?

    herbs2Mongo is just one of many bridges possible between Herbs and other packages.

    The advantage of using Mongo is that is a simple and flexible way to retrieve data from MongoDB, as a plus we're using the oficial driver from MongoDB here.

    Repository setup

    const { Repository } = require('@herbsjs/herbs2mongo')
    const connection = require('connection')  // Mongo initialize instance
    const { ProductItem } = require('../domain/entities/productItem')
    const database = 'herbs2mongo_testdb'
    
    class YourRepository extends Repository {
        constructor() {
            super({
                entity: ProductItem,
                collection: 'product_items',
                database,
                ids: ['id'],
                mongodb: connection
            })
        }
    }
    • entity - The Entity to be used as reference

      entity: ProductItem
    • collection - The name of the collection in database

      collection: 'product_items'
    • database - The name of the database

      database: 'herbs2mongo_testdb'
    • ids - Primary keys

      Format: ['fieldName', 'fieldName', ...]

      There must be corresponding fields in the entity.

      ids: ['id']  // productItem.id

      or for composite primary key:

      ids: [`customerId`, `productId`]  // productItem.customerId , productItem.productId
    • mongoDB - mongoDB driver initialize instance

      Check mongoDB documentation

    Retrieving and Persisting Data

    find

    Find entities

    Format: .find(options) where options is a optional object containing { limit, skip, orderBy, filter }

    Return: Entity array

    const repo = new ItemRepository(injection)
    const ret = await repo.find()

    Options:

    • limit Adds a limit clause to the query.
    const repo = new ItemRepository(injection)
    const ret = await repo.find({ limit: 10 })
    • skip Adds an skip clause to the query.
    const repo = new ItemRepository(injection)
    const ret = await repo.find({ offset: 5 })
    • orderBy Adds an order by clause to the query. Column can be string, or list mixed with string and object.
    // order by collum
    const repo = new ItemRepository(injection)
    const ret = await repo.find({ orderBy: 'description'})
    • filter Adds a filter to the query with given values.
    const repo = new ItemRepository(injection)
    const ret = await repo.find({ filter: { stringTest: ["aString"] } })
    • find with native parameters You also can use the method find to use the mongoDB native parameters
    const { ObjectId } = require('mongodb')
    
    const repo = new ItemRepository(injection)
    const ret = await repo.find({ _id : { $in : [ObjectId('4323fefwed4234'), ObjectId('3432d23232dfff')] } } )
    const { ObjectId } = require('mongodb')
    
    const repo = new ItemRepository(injection)
    const ret = await repo.find({ _id : { $in : [ObjectId('4323fefwed4234'), ObjectId('3432d23232dfff')] } } )
    • findAll You also findAll records using the native find without filters
    const repo = new ItemRepository(injection)
    const ret = await repo.find({ } )

    findByID

    Find entities by IDs

    Format: .findByID(id) where id is a ObjectId string or array, this will be changed to _id automaticaly

    Return: Entity array

    const repo = new ItemRepository(injection)
    const ret = await repo.findByID('60edc25fc39277307ca9a7ff')

    or

     const ids = [
                '60edc25fc39277307ca9a7ff',
                '80edd25fc39272307ca9a712',
              ]
    
    const repo = new ItemRepository(injection)
    const ret = await repo.findByID(ids)

    insert

    Insert an Entity into a table.

    Format: .insert(entity) where entity is a Entity instance with values to be persisted.

    Return: The inserted entity with the values from database.

    const repo = new ItemRepository(injection)
    const ret = await repo.insert(aNewEntity)

    insertMany

    Insert an array of Entities into a table.

    Format: .insertMany([entity]) where [entity] is a array of Entities instances with values to be persisted.

    Return: The inserted id's in ObjectId format with the values from database.

    const aNewArrayofEntities = [
      givenAnEntity('string one test',false),
      givenAnEntity('string two test',true)
    ]
    
    const repo = new ItemRepository(injection)
    const ret = await repo.insertMany(aNewArrayofEntities)

    update

    Update an Entity.

    Format: .update(entity) where entity is a Entity instance with values to be persisted.

    Return: The updated entity with the values from database.

    const repo = new ItemRepository(injection)
    const ret = await repo.update(aModifiedEntity)

    updateMany

    Update a group of Entities.

    Format: .updateMany(options) where options is a set of conditionals and new values to set a group of entities

    Return: The updated entity with the values from database.

    const repo = new ItemRepository(injection)
    let filterDefinition = { id: anEntity.id  }
    let updateDefinition = { $set: { "stringTest" : "everything works very well" } }
    await itemRepo.updateMany({ filter: filterDefinition, update: updateDefinition})

    deleteByID

    Delete an Entity.

    Format: .deleteByID(id) where id is a ObjectId string, this will be changed to _id automaticaly.

    Return: true for success or false for error

    const repo = new ItemRepository(injection)
    const ret = await repo.deleteByID(entity)

    deleteMany

    Delete a group of Entities.

    Format: .deleteMany(options = { filter}) where options is a set of filters to be deleted.

    Return: true for success or false for error

    const repo = new ItemRepository(injection)
    let filterDefinition = {  numberTest : [aModifiedInstance.numberTest] }
    const ret = await repo.deleteMany({ filter: filterDefinition })

    delete

    Delete an Entitie.

    Format: .delete(entity) where entity is a Entity instance to be deleted.

    Return: true for success or false for error

    const repo = new ItemRepository(injection)
    const ret = await repo.delete(aModifiedEntity)

    TODO

    • [ ] Allow only scalar types for queries (don't allow entity / object types)
    • [ ] Allow to ommit database name

    Features:

    • [ ] Be able to change the conventions (injection)
    • [ ] Exclude / ignore fields on all query statement
    • [ ] Awareness of created/updated at/by fields
    • [X] Plug-and-play MongoDB

    Retrieving and Persist:

    • [X] insert
      • [X] batchs (insertMany)
    • [X] update
      • [X] batchs (updateMany)
    • [X] delete (id)
      • [X] batchs (deleteMany)
    • [ ] persist (upsert)
    • [X] find (ID)
      • [ ] deal with entities / tables with custom _ids
    • [X] find by (any field)
      • [ ] deal with entities / tables with custom _ids
      • [X] order by
      • [X] limit
      • [X] skip
    • [X] find All
      • [X] order by
      • [X] limit
      • [X] skip
    • [X] find with pages
    • [ ] agregations
    • [ ] replace
    • [ ] collation
    • [ ] watch
    • [ ] first
    • [ ] last

    Tests:

    • [X] Pure JS
    • [X] MongoDB

    Contribute

    Come with us to make an awesome herbs2mongo.

    Now, if you do not have the technical knowledge and also have intended to help us, do not feel shy, click here to open an issue and collaborate their ideas, the contribution may be a criticism or a compliment (why not?)

    If you would like to help contribute to this repository, please see CONTRIBUTING

    Install

    npm i @herbsjs/herbs2mongo

    DownloadsWeekly Downloads

    202

    Version

    3.0.2

    License

    MIT

    Unpacked Size

    105 kB

    Total Files

    48

    Last publish

    Collaborators

    • herbsjs-robot
    • dalssoft
    • jhomarolo