npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

mongoose-materialized

v0.2.0

Published

Materialized path hierarchy for mongoose

Downloads

6,422

Readme

Mongoose Materialized

Build Status NPM version

A mongoose plugin for the materialized paths.

Overview


Usage

var mongoose = require('mongoose'),
    materializedPlugin = require('mongoose-materialized'),
    Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/materialized');

var CatSchema = new Schema({
  name: {type: String}
});


CatSchema.plugin(materializedPlugin);

var Cat= mongoose.model('Cat', CatSchema); // Category

Go to contents


Examples

Adding root and child element.

Important: The model verifies the existence of the parent category before they would save. Except for the root element or change the parent id not touch.

// if you have predefined datas with parent id
Cat.Building(function(){
    // building materialized path
});

// add root element
cat = new Cat({name: "Foods"});
cat.save(function(err, foods){
    // append new sub category
    foods.appendChild({name: "Vegetables"}, function(err, vega){
        // vega: { name: "Vegetables", parentId: [foods ID], path: ',[foods ID]' }
    });
    // or make new
    var vega = new Cat({name: "Vegetables"});
    // saving with append
    foods.appendChild(vega, function(err, data){ ... });
    // or save traditional way
    vega.parentId = foods._id;
    vega.save(function(err, data){ ... });
});

Find element and checking the relationship

Cat.findOne({parentId: null}, function(err, doc){
    // access to the children
    doc.getChildren(function(err, docs){
        // ...
    });

    // access to the children with condition and sort
    doc.getChildren({
        condition: { name: /^a/ },
        sort: { name: 1 }
    },function(err, docs){
        // ...
    });

    // access to the siblings
    doc.getSiblings(function(err, docs){
        // ...
    });

    // access to the ancestors
    doc.getAncestors(function(err, docs){
        // ...
    });

    // check element is root
    doc.isRoot(function(err, isOk){ ... });

    // check element is leaf
    doc.isLeaf(function(err, isLeaf){ ... });

    // depth virtual attributes
    doc.depth

    // use promise
    doc.getChildren().then(function(docs){
        // ...
    });

    // get doc array tree
    doc.getArrayTree(function(err, tree){
        // ... [ {"_id": "...", "children": [ {...} ]}]
    });

    // get doc tree
    doc.getTree(function(err, tree){
        // ... { "doc ID": { ..., children: { ... } }
    });

    // or get tree with condition and sorting
    doc.getTree({
        condition: { name: /^[a-zA-Z]+$/ },
        sort: { name: 1 }
    }, function(err, tree){
        // ...
    });
});

Cat.GetTree('elemt ID', function (err, tree) {
    // ...
});

Cat.GetArrayTree('elemt ID', function (err, tree) {
    // ...
});

// access for full tree in array
Cat.GetFullArrayTree(function (err, tree) {

});

// access for full tree object
Cat.GetFullTree(function (err, tree) {

});

The different arrayTree and simple Tree methods: arrayTree result:

[ 
    { _id: 53ee2db76f2d838a07a04e6a,
    path: '',
    name: 'Foods',
    __v: 0,
    _w: 0,
    parentId: null,
    depth: 0,
    id: '53ee2db76f2d838a07a04e6a',
    children: [ [Object], [Object] ] 
    }
]

and the Tree result:

{ '53ee2db76f2d838a07a04e6a': 
   { _id: 53ee2db76f2d838a07a04e6a,
     path: '',
     name: 'Foods',
     __v: 0,
     _w: 0,
     parentId: null,
     depth: 0,
     id: '53ee2db76f2d838a07a04e6a',
     children: { 
        '53ee2db76f2d838a07a04e6b': [Object] 
        } 
    } 
}

Manipulate child element with static method mongoose-materialized it is possible to use more than one root.

Cat.AppendChild('ID', { 'name': 'Meats'}, function(err, doc){ ... });
Cat.getChildren('ID', function(err, childs){ ... });
Cat.getRoots(function(err, roots){
    // root elements
});

// Format tree, sub element stored in children field
Cat.getRoots({ name: "" }).then(function (err, root) {
    root.getChildren().then(function (err, children) {
        console.log( Cat.toTree(children) );
        // or only shown name
        console.log( Cat.toTree(children, { name: 1 }) );
    });
});

Hierarchical builder for the existing data. Important: This operation is relatively slow. Use only the conversion.

Cat.Building(function(){
    // builded materialized path sturcture
});

// This example convert nested set to materialized path. Use this function to migration.

Cat.Building({
    remove: { lt: 1, gt: 1, children: 1 } // remove nested fields from existsing data
}, function(){
    // building is competted
});

Go to contents


API

Instructions

The following methods must be used with a callback. The callback method have two arguments. The first error and the second data object. If all goes well then the error is null.

model.calledFunction( function (error, data) {
    if (error)
        // handle error
});

The methods with work callback return promise. Mongoose Promise

model.calledFunction().then( function (data) {

}, function (err) {
    // handle error
});

Imprtant! Do not use the following methods:

  • Model.findByIdAndUpdate()
  • Model.findByOneAndUpdate()
  • Model.findByIdAndRemove()
  • Model.findByOneAndRemove()
  • Model.update() - static version
  • instance.update()
  • Model.remove() - static version

These functions are not triggered by the removal and saving events.

Instead, the following are recommended:

  • instance.save() - saving and update (before use findOne, findById)
  • instance.remove() - remove document (before use findOne, findById)
  • Model.Remove(condition, callback)

The my query object is special object for mongo query. This parameter available for functions.

var query = {
    // mongo condition
    condition: {
        name: /^a/
    },
    // selected fields
    fields: {
        _id: 1,
        name: 1
    },
    // sorting
    sort: {
        name: -1
    }
};

// Example get chidls with query
doc.getChilds(query, function(err, docs){ ... });

To run the tests:

npm test

Go to contents


Attributes

Added attributes:

  • parentId: Parent item id.
  • path: materialized path. Auto generated
  • _w: weight for sort
  • depth: (virtual) element depth

Go to contents


Static methods

Similar method has the static begins with the first letter capitalized. (IsLeaft is static and isLeaf non static)

  • IsLeaf(ModelOrId, callback)

  • IsRoot(ModelOrId, callback)

  • GetChildren(ModelOrId, [query,] callback)

  • GetRoots([query,] callback)

  • GetTree(root condition, [children query,] callback) - get elemets tree with children

  • GetFullTree(callback)

  • GetArrayTree(root condition, [children query,] callback) - get elemets tree with children

  • GetFullArrayTree(callback)

  • Remove(condition, callback) - use this instead of remove.

  • AppendChild(ModelOrId, callback)

  • ToTree(documentArray, selected fields) Return object, no mongoose document (toObject()). Fields: { name: 1, _id: 1 }

  • ToArrayTree(documentArray, selected fields) Return objects in array, no mongoose document (toObject()). Fields: { name: 1, _id: 1 }

  • Building([prepare,] callback) - rebuild material path (good for extisting collections - parentId is needed)

Go to contents


Methods

  • isRoot(callback)

  • isLeaf(callback)

  • isDescendant(callback)

  • isParent(ModelOrId, callback)

  • isSibling(ModelOrID, callback)

  • getParent(callback)

  • getDescendants([query,] callback)

  • getChildren([query,] callback) alias for getDescendants

  • getAncestors([query,] callback)

  • getSiblings([query,] callback)

  • getTree([query,] callback) - get elemets tree with children

  • getArrayTree([query,] callback) - get elemets tree with children, array version

  • appendChild(model, callback)

  • setParent(ModelOrId) - if parameter is ID then check parent existence and set parentId (the model parameter to avoid the query)

  • getChildCondition()

  • getAncestorsCondition()

  • getSiblingsCondition()

Go to contents


Related Links

Inspired by seamless data management.

Go to contents


Changelog

Oct 28, 2017 - version: 0.2.0

  • fixed update children behavior. Thanks @selcukfatihsevinc
  • updated dependencies: mongoose 4.12.* , Async 2.5.*
  • added support nodejs 8.0
  • dropped support nodejs 0.6, 0.8

Nov 10, 2016 - version: 0.1.9

  • fixed MongoDB 3.2 limit issue. Thanks @alexjamesbrown
  • fixed dependency: should package

Aug 15, 2014 - version: 0.1.8

  • added new static methods: ToArrayTree(), GetArrayTree(), GetFullArrayTree()
  • added new methods: getArrayTree()
  • added new tests
  • enhancements (toTree, parentId type inherits from _id)
  • updated README.md and package dependencies

July 30, 2014 - version: 0.1.7

  • fixed remove parent with parentId=null bug
  • added new tests
  • updated README.md

Dec 19, 2013 - version: 0.1.6

  • added requested function: skip, limit for getDescendants, getChildren, getAncestors, getSiblings
  • in tree construction (getTree, buildTree) skip, limit methods is not recommended for use

Oct 15, 2013 - version: 0.1.5

  • fixed typo in 153 line.

Jun 25, 2013 - version: 0.1.4

  • ToTree use virtuals
  • better depth solution

Jun 16, 2013 - version: 0.1.3

  • added GetFullTree static method
  • added prepare for Building - use: Building({ remove: { lt: 1, gt: 1, level: 1 }, function () { });
  • added GetFullTree test

Jun 16, 2013 - version: 0.1.2

  • added getTree method and GetTree static method
  • added Remove static method for remove with condition
  • fixed: getChildren now return promise
  • fixed: GetRoots function call
  • fixed: GetChildren function call
  • Building method already work
  • Building tests
  • updated README.md

Jun 14, 2013 - version: 0.1.1

  • added ToTree test
  • tempory removed Building static method (thown not implemented error if use)
  • fixed: ToTree now return json document. (Not mongoose document)
  • updated README.md

Jun 10, 2013 - version: 0.1.0

  • currently under construction
  • added test
  • static methods
  • before save verifies the existence of parent element
  • Query supported methods
  • added Travis CI build status
  • updated README.md

Go to contents


authors

Go to contents