PHPackages                             trismegiste/yuurei - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Database &amp; ORM](/categories/database)
4. /
5. trismegiste/yuurei

Abandoned → [trismegiste/strangelove-bundle](/?search=trismegiste%2Fstrangelove-bundle)ArchivedLibrary[Database &amp; ORM](/categories/database)

trismegiste/yuurei
==================

Schemaless Object Document Mapper for MongoDB

v2.3.2(10y ago)21311MITPHPPHP &gt;=5.5

Since Dec 8Pushed 10y ago1 watchersCompare

[ Source](https://github.com/Trismegiste/Yuurei)[ Packagist](https://packagist.org/packages/trismegiste/yuurei)[ RSS](/packages/trismegiste-yuurei/feed)WikiDiscussions master Synced 2mo ago

READMEChangelogDependencies (2)Versions (7)Used By (1)

Yuurei (幽霊) [![Build Status](https://camo.githubusercontent.com/97b3f95ead573a1f4285beb8335febc87186b8729af2469b4ce0e8bafd5de560/68747470733a2f2f7472617669732d63692e6f72672f547269736d6567697374652f5975757265692e706e673f6272616e63683d6d6173746572)](https://travis-ci.org/Trismegiste/Yuurei)
=================================================================================================================================================================================================================================================================================================

[](#yuurei-幽霊-)

[![Yo dawg Xzibit](./doc/img/atomicity.jpg)](./doc/img/atomicity.jpg)

Atomicity in [MongoDB](http://www.mongodb.org/) explained by Xzibit

What
----

[](#what)

It's a micro database layer with automatic mapping. It is intended for **advanced users** of [MongoDB](http://www.mongodb.org/)who know and understand the growth of a model on a schemaless database.

When I mean "micro", I mean the sum of NCLOC is less than the infamous method [UnitOfWork::createEntity](https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/UnitOfWork.php#L2446) of Doctrine 2

Of course, features are also "micro". Don't expect the impossible. Nevertheless there are some functionalities you don't find anywhere else.

Plus, this DBAL is fully extendable. My other repo [DokudokiBundle](https://github.com/Trismegiste/DokudokiBundle) for symfony2 adds 3 more mapping systems with minimum coding.

How
---

[](#how)

Use Composer like any other PHP package :

```
 $ composer.phar require trismegiste/yuurei dev-master

```

Why
---

[](#why)

Because, like the cake, "ODM is a lie". Turning MongoDB into an ORM-like abstraction is the worst thing you can do against a NoSQL database.

With an ODM, you loose both NoSQL and RDBMS features, here are some :

- No rich document of MongoDB because the query generator sux and the mapping is complex
- No schemaless capability because you freeze the model in classes
- No JOIN, you must rely on slow lazy loading
- No constraint of RDBMS (references and types) because there is none
- No atomicity : the only atomicity in MongoDB is on one document

In fact ODM is a slow [ORM](http://en.wikipedia.org/wiki/Object-relational_mapping) without [ACID](http://en.wikipedia.org/wiki/ACID) : what is the point of using MongoDB ?

That's why I stop chasing the ["Mythical Object Database"](http://en.wikipedia.org/wiki/Object_database) and start hacking.

Guidances
---------

[](#guidances)

- **Rich documents** by Hell ! You have atomicity.
- Stop to think 1 entity &lt;=&gt; 1 table
- Only a few root entities : 2, 3 or 4, 10 max for a full e-commerce app, not 200 !
- 1 app &lt;=&gt; 1 collection
- Forget 1NF, 2NF and 3NF. It's easier to deal with denormalized data in MongoDB than to too many LEFT JOIN in MySQL
- Think like serialize/unserialize
- Don't try to reproduce a search engine with your database : use [Elastic Search](http://www.elasticsearch.org/)
- Don't try to store everything in collections : use XML files

So, you make a model divided in few parts without circular reference, and you store it. It's like serialization but in MongoDB.

All non static properties are stored in a way you can query easily with the powerfull (but very strange I admit) language of MongoDB.

See the [PHPUnit tests](https://github.com/Trismegiste/Yuurei/tree/master/tests/Yuurei/DumperExampleTest.php#L28) for examples of the serialization process.

It's like serialization
-----------------------

[](#its-like-serialization)

You know PHP can save and restore any object in session with the serialization and it doesn't need any mapping information, annotations nor repositories. This was my paradigm when I started this library.

Why can't an ORM/ODM do the same ? Well, of course I needed a NoSQL database. But this dbal/odm-like does not need any mappping information and objects stored in the database are keeping their original structures (without too much noise). So you can make complex queries with MongoDb.

See full example in [unit test](https://github.com/Trismegiste/Yuurei/tree/master/tests/Yuurei/ReadmeExampleTest.php#L28)

```
// simple object
$doc = new \Some\Sample\Product('EF-85 L', 2000);
// persisting
$this->invocation->persist($doc);
// restoring with invocation repository
$restore = $this->invocation->findByPk((string) $doc->getId());
$this->assertInstanceOf('Some\Sample\Product', $restore);
// retrieving the content in the MongoDB
$dump = $this->collection->findOne(array('_id' => $doc->getId()));
$this->assertEquals('Some\Sample\Product', $dump['-fqcn']);  // we store the FQCN
$this->assertEquals('EF-85 L', $dump['title']);
$this->assertEquals(2000, $dump['price']);
```

About MDE
---------

[](#about-mde)

With recent concepts of NoSQL, SOA and HMVC, I believe MDE is somewhat past-history, not always but very often. In fact it's not the MDE itself but a very common anti-pattern : the "Database Driven Development" where all source code come from the database schema. Combined with CRUD generators, it leads to [anemic model](http://en.wikipedia.org/wiki/Anemic_domain_model), dumb constructors and useless setters/getters without business meaning.

About performance
-----------------

[](#about-performance)

todo

FAQ
---

[](#faq)

### What are the requirements ?

[](#what-are-the-requirements-)

- PHP &gt;= 5.4
- PECL Mongo extension &gt;= 1.3

### How to map properties ?

[](#how-to-map-properties-)

All *object's* properties are stored. You have only one thing to do : The root classes must implement the Persistable interface (there is a trait for implementing this interface). You don't need to extend any particuliar class, therefore you can follow the DDD without constraint.

### What is a "root class" ?

[](#what-is-a-root-class-)

It is a class stored in the collection, which contains the MongoId in the key '\_id'. All other agregated objects in this class don't need to implement Persistable, they are recursively stored.

### What are the constraints ?

[](#what-are-the-constraints-)

This library cannot save &amp; restore private properties coming from a parent class. Private properties in persisted classes are ok but they will not be seen by subclasses and therefore cannot be persisted if you save these subclasses in the database. This is a big limitations so be careful when you use the keyword 'private'.

### How can I remove some transient properties ?

[](#how-can-i-remove-some-transient-properties-)

You can't. But you can have a transient class with the interface Skippable. Use Decorator pattern or a State Pattern. Your model can do that.

### Can I make some cleaning before persistence ?

[](#can-i-make-some-cleaning-before-persistence-)

Like serialization, you can implement Cleanable with 2 methods : wakeup and sleep

### How can I query for listing ?

[](#how-can-i-query-for-listing-)

Use the MongoCollection, you can't be more efficient than this low level layer

### How can I store pictures or PDF ?

[](#how-can-i-store-pictures-or-pdf-)

Use a MongoBinData in your model, it is stored as is

### Can I use something else than MongoId for primary key ?

[](#can-i-use-something-else-than-mongoid-for-primary-key-)

No. Of course MongoDB allow you to use something else but it is not a very good idea for the most case.

### What about MongoDate ?

[](#what-about-mongodate-)

Any DateTime are converted into MongoDate and vice versa.

### What are the guidances you have used for this lib ?

[](#what-are-the-guidances-you-have-used-for-this-lib-)

- No mandatory inheritance for model except one interface (for DDD concern)
- Minimum number of switch because it is hidden inheritance
- No more than 5 methods per class
- No method longer than 20 NCLOC
- No static because it is global
- [SRP, OCP, LSP, ISP, DIP](http://en.wikipedia.org/wiki/SOLID_(object-oriented_design)) at maximum level
- coupling at minimum level (checked with [Mondrian](https://github.com/Trismegiste/Mondrian) )

### Is there any lazy loading or proxy classes for DBRef ?

[](#is-there-any-lazy-loading-or-proxy-classes-for-dbref-)

Fly, you fools

What is the meaning of Yuurei ?
-------------------------------

[](#what-is-the-meaning-of-yuurei-)

In fact this lib was part of [DokudokiBundle](https://github.com/Trismegiste/DokudokiBundle) and I wanted to keep the best from this Bundle in a standalone library. So I kept a japanese name for this. 幽霊 means ghost or spirit because in the original bundle, this mapping system was named "Invocation".

###  Health Score

29

—

LowBetter than 60% of packages

Maintenance20

Infrequent updates — may be unmaintained

Popularity13

Limited adoption so far

Community9

Small or concentrated contributor base

Maturity62

Established project with proven stability

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~120 days

Recently: every ~85 days

Total

6

Last Release

3932d ago

PHP version history (3 changes)2.0PHP &gt;=5.4

v2.1.0PHP &gt;=5.4.3

v2.3.0PHP &gt;=5.5

### Community

Maintainers

![](https://www.gravatar.com/avatar/64cc99ca21a090b2454784670e4ac49db17794d6861078eeceebdbe302365c3f?d=identicon)[trismegiste](/maintainers/trismegiste)

---

Top Contributors

[![Trismegiste](https://avatars.githubusercontent.com/u/1260026?v=4)](https://github.com/Trismegiste "Trismegiste (34 commits)")

---

Tags

dbalnosqlodmmongodbmicroframework

### Embed Badge

![Health badge](/badges/trismegiste-yuurei/health.svg)

```
[![Health](https://phpackages.com/badges/trismegiste-yuurei/health.svg)](https://phpackages.com/packages/trismegiste-yuurei)
```

###  Alternatives

[doctrine/mongodb-odm

PHP Doctrine MongoDB Object Document Mapper (ODM) provides transparent persistence for PHP objects to MongoDB.

1.1k23.3M301](/packages/doctrine-mongodb-odm)[sokil/php-mongo

PHP Object Document Mapper for MongoDB

239161.5k9](/packages/sokil-php-mongo)[leroy-merlin-br/mongolid-laravel

Easy, powerful and ultrafast MongoDB ODM for Laravel.

23827.8k2](/packages/leroy-merlin-br-mongolid-laravel)[leroy-merlin-br/mongolid

Easy, powerful and ultrafast ODM for PHP and MongoDB.

11234.3k4](/packages/leroy-merlin-br-mongolid)[mmucklo/queue-bundle

Symfony2/3/4/5 Queue Bundle (for background jobs) supporting Mongo (Doctrine ODM), Mysql (and any Doctrine ORM), RabbitMQ, Beanstalkd, Redis, and ... {write your own}

120839.8k](/packages/mmucklo-queue-bundle)[doctrine/doctrine-mongo-odm-module

Laminas Module which provides Doctrine MongoDB ODM functionality

86676.6k35](/packages/doctrine-doctrine-mongo-odm-module)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
