项目作者: vikpe

项目描述 :
Mongoose plugin for tree hierarchy using the materialized path pattern.
高级语言: JavaScript
项目地址: git://github.com/vikpe/mongoose-mpath.git
创建时间: 2017-09-15T15:50:11Z
项目社区:https://github.com/vikpe/mongoose-mpath

开源协议:MIT License

下载


Mongoose Materialized Path npm version test codecov

Mongoose plugin for tree hierarchy using the materialized path pattern.

Requirements

  • Node.js >= 14
  • MongoDB >= 4
  • Mongoose >= 6

Installation

  1. npm install mongoose-mpath

Setup

Important note

This plugins adds parent, path and children fields to the schema. You should not define them in the schema which the plugin is enabled on.

Semantics

  1. MySchema.plugin(MpathPlugin, [PLUGIN OPTIONS]);

Plugin options

  1. const options = {
  2. modelName: 'MyModel', // Name of model
  3. pathSeparator: '#', // (optional) String used to separate ids in path
  4. onDelete: 'REPARENT', // (optional) 'REPARENT' or 'DELETE'
  5. idType: Schema.ObjectId // (optional) Type used for model id
  6. }

Example setup

  1. import Mongoose from 'mongoose';
  2. import MpathPlugin from 'mongoose-mpath';
  3. const LocationSchema = new Mongoose.Schema({name: String});
  4. LocationSchema.plugin(MpathPlugin, {modelName: 'Location'});
  5. const LocationModel = Mongoose.model('Location', LocationSchema);
  6. const europe = new LocationModel({name: 'europe'});
  7. const sweden = new LocationModel({name: 'sweden', parent: europe});
  8. const stockholm = new LocationModel({name: 'stockholm', parent: sweden});
  9. await europe.save();
  10. await sweden.save();
  11. await stockholm.save();

At this point in mongoDB you will have documents similar to

  1. {
  2. "_id" : ObjectId("50136e40c78c4b9403000001"),
  3. "name" : "europe",
  4. "path" : "50136e40c78c4b9403000001"
  5. }
  6. {
  7. "_id" : ObjectId("50136e40c78c4b9403000002"),
  8. "name" : "sweden",
  9. "parent" : ObjectId("50136e40c78c4b9403000001"),
  10. "path" : "50136e40c78c4b9403000001#50136e40c78c4b9403000002"
  11. }
  12. {
  13. "_id" : ObjectId("50136e40c78c4b9403000003"),
  14. "name" : "stockholm",
  15. "parent" : ObjectId("50136e40c78c4b9403000002"),
  16. "path" : "50136e40c78c4b9403000001#50136e40c78c4b9403000002#50136e40c78c4b9403000003"
  17. }

The path is used for recursive methods and is kept up to date by the plugin if the parent is changed.

API

All examples below are based on the following document hierarchy:

  1. africa
  2. europe
  3. - norway
  4. - sweden
  5. -- stockholm
  6. --- skansen

getAncestors()

Returns ancestors of a document. Returns a promise.

Signature

  1. document.getAncestors(conditions, [fields], [options])

Arguments

  • See offical docs on model.find() for description of arguments.

Example

  1. const ancestors = await stockholm.getAncestors({}); // (Array) [europe, sweden]

getAllChildren()

Returns all children of a document. Returns a promise.

Signature

  1. document.getAllChildren(conditions, [fields], [options])

Arguments

  • See offical docs on model.find() for description of arguments.

Example

  1. const children = await sweden.getAllChildren({}); // (Array) [stockholm, skansen]
  2. const children = await stockholm.getAllChildren({}); // (Array) [skansen]

getChildrenTree()

Returns all children of a document formatted as a tree hierarchy. Returns a promise.

Signature

  1. document.getChildrenTree([args]) // as method
  2. model.getChildrenTree([args]) // as static

Arguments

  • (Object) args

    1. {
    2. (Object) filters: {}, // mongoose query filters
    3. (Object|String) fields: null, // mongoose query fields (null equals all fields)
    4. (Object) options: {}, // mongoose query options
    5. (String) populate: '', // string to passed to populate()
    6. (int) minLevel: 1, // minimum level to include
    7. (int) maxLevel: 9999, // maximum level to include
    8. (Mongoose.document) rootDoc // mongoose document
    9. }

    Example

    1. const args = {
    2. filters: {author: 'vikpe'},
    3. fields: '_id name',
    4. options: {sort: 'name'},
    5. populate: 'repos',
    6. minLevel: 2,
    7. maxLevel: 4
    8. }

Example

  1. const tree = await sweden.getChildrenTree({});
  2. // tree is an array similar to
  3. /*
  4. [
  5. {
  6. 'name': 'sthlm',
  7. 'children': [
  8. {
  9. 'name': 'skansen',
  10. 'children': [],
  11. }
  12. ],
  13. }
  14. ]
  15. */

getImmediateChildren()

Returns immediate children of a document. Returns a promise.

Signature

  1. document.getImmediateChildren(conditions, [fields], [options])

Arguments

  • See offical docs on model.find() for description of arguments.

Example

  1. const children = await europe.getImmediateChildren({}); // (Array) [norway, sweden]
  2. const children = await sweden.getImmediateChildren({}); // (Array) [stockholm]

getParent()

Returns parent of a document.

Signature

  1. document.getParent([fields], [options])

Arguments

  • See offical docs on model.find() for description of arguments.

Example

  1. const parent = await sweden.getParent(); // (Object) europe
  2. const parent = await stockholm.getParent(); // (Object) sweden

level

A Virtual field that equals to the level of a document in the hierarchy.

Signature

  1. (Number) document.level

Example

  1. africa.level // 1
  2. sweden.level // 2
  3. skansen.level // 4

children

Placeholder variable populated when calling .getChildrenTree().

More examples

Given the following document hierarchy:

  1. africa
  2. europe
  3. - norway
  4. - sweden
  5. -- stockholm
  6. --- skansen

getAncestors()

  1. europe.getAncestors() // (Array) []
  2. stockholm.getAncestors() // (Array) [europe, sweden]
  3. skansen.getAncestors() // (Array) [europe, sweden, stockholm]

getAllChildren()

  1. europe.getAllChildren() // (Array) [sweden, stockholm, skansen]
  2. stockholm.getAllChildren() // (Array) [skansen]
  3. skansen.getAllChildren() // (Array) []

getImmediateChildren()

  1. europe.getImmediateChildren() // (Array) [norway, sweden]
  2. stockholm.getImmediateChildren() // (Array) [skansen]
  3. skansen.getImmediateChildren() // (Array) []

getChildrenTree()

  1. europe.getChildrenTree()
  2. /*
  3. [
  4. {
  5. 'name': 'norway',
  6. 'children': []
  7. },
  8. {
  9. 'name': 'sweden',
  10. 'children': [
  11. {
  12. 'name': 'sthlm',
  13. 'children': [
  14. {
  15. 'name': 'skansen',
  16. 'children': []
  17. }
  18. ],
  19. }
  20. ]
  21. }
  22. ]
  23. */
  24. sweden.getChildrenTree()
  25. /*
  26. [
  27. {
  28. 'name': 'sthlm',
  29. 'children': [
  30. {
  31. 'name': 'skansen',
  32. 'children': [],
  33. }
  34. ],
  35. }
  36. ]
  37. */

getParent()

  1. europe.getParent() // (null)
  2. stockholm.getParent() // (Object) sweden
  3. skansen.getParent() // (Object) stockholm

level

  1. africa.level // (Number) 1
  2. europe.level // (Number) 1
  3. norway.level // (Number) 2
  4. sweden.level // (Number) 2
  5. stockholm.level // (Number) 3
  6. skansen.level // (Number) 4

Development

Feedback and pull requests are most welcome!

  1. npm install mongoose-mpath
  2. Install MongoDB (Community Server).
  3. Start MongoDB: mongod
  4. Run tests: npm run test

Credits

This plugin is inspired by mongoose-path-tree by swayf.