PHPackages                             trismegiste/dokudoki - 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/dokudoki

AbandonedArchivedSymfony-bundle[Database &amp; ORM](/categories/database)

trismegiste/dokudoki
====================

Schemaless database layer for MongoDB and helpers for schemaless capabilities

v2.3.2(10y ago)4117[1 issues](https://github.com/Trismegiste/DokudokiBundle/issues)MITPHPPHP &gt;=5.5

Since Mar 14Pushed 10y ago1 watchersCompare

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

READMEChangelogDependencies (8)Versions (10)Used By (0)

DokudokiBundle [![Build Status](https://camo.githubusercontent.com/5ad41406544fafbf479b7e2a141e078255de1bff982759732d53d1f562f9dccf/68747470733a2f2f7472617669732d63692e6f72672f547269736d6567697374652f446f6b75646f6b6942756e646c652e706e673f6272616e63683d6d6173746572)](https://travis-ci.org/Trismegiste/DokudokiBundle)
============================================================================================================================================================================================================================================================================================================================

[](#dokudokibundle-)

What
----

[](#what)

It's a bundle based on [Yuurei](https://github.com/Trismegiste/Yuurei), a micro database layer with automatic mapping.

This bundle adds multiple features aside from the original mapping of Yuurei : 3 others mapping systems (full magic, aliasing and mix of both), form components to handle MongoDate and uploaded files, DataCollector for WebProfiler and of course, a lot of services injected in the DiC of symfony2.

I try to make an agnostic DBAL which *helps*you in the process to build an app regardless the model is finished or not. So there is also migration tools.

How
---

[](#how)

Use Composer like any other PHP package :

### For Symfony 2.3

[](#for-symfony-23)

```
    "require": {
        "trismegiste/dokudoki": "dev-master"
    },

```

### Legacy for Symfony 2.x

[](#legacy-for-symfony-2x)

```
    "require": {
        "trismegiste/dokudoki": "dev-Symfony2.x"
    },

```

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.

I'm fed up by both CRUD antipattern and anemic model produced by ORM and code generators. In the end, you realized that you must model your classes for the ORM and not for the business. I wanted to restore the Domain Driven Development philosophy developed in Symfony2 and ruined by Doctrine2.

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/DokudokiBundle/blob/master/tests/DokudokiBundle/ReadmeExampleTest.php) for examples.

Four modes of working
---------------------

[](#four-modes-of-working)

This DBAL has 4 stages, regarding the completion of the model classes.

The trick is you can migrate between these stages when you develop your app and, for example, don't need to start over after a dirty prototype. You even can generate a model from the data you had stored into collections when you don't have one.

See [Examples of using this dbal in PHPUnit Tests](https://github.com/Trismegiste/DokudokiBundle/blob/master/tests/DokudokiBundle/ReadmeExampleTest.php)

### Black Magic is black

[](#black-magic-is-black)

If you have no model and a lot of forms to design, start with the "BlackMagic" stage. If an anemic model is enough for you, don't create one. It is full of magic methods, magic mapping and magic documents, it's like working with mockup.

But be warned : it is for prototyping and your database can turn back against you if you are not careful. That's what I call "Form Driven Development".

See full example in [unit test](https://github.com/Trismegiste/DokudokiBundle/blob/master/tests/DokudokiBundle/ReadmeExampleTest.php#L47)

```
// construct a form
$form = $this->formFactory
        ->createBuilder('magic_form', null, array('class_key' => 'product'))
        ->add('title')
        ->add('price')
        ->getForm();
// bind data to the form
$form->bind(array('title' => 'EF-85 L', 'price' => 2000));
$doc = $form->getData();
// getting the magic document
$this->assertInstanceOf('Trismegiste\DokudokiBundle\Magic\Document', $doc);
$this->assertEquals('product', $doc->getClassName());
$this->assertEquals('EF-85 L', $doc->getTitle());
// persistence with blackmagic repository
$this->blackmagic->persist($doc);
// restoring with blackmagic repository
$restore = $this->blackmagic->findByPk((string) $doc->getId());
$this->assertInstanceOf('Trismegiste\DokudokiBundle\Magic\Document', $restore);
$this->assertEquals('product', $restore->getClassName());
$this->assertEquals('EF-85 L', $restore->getTitle());
```

### Serialization could be enough

[](#serialization-could-be-enough)

This is the original mapping system from Yuurei. If you have a lot of nearly complete model classes and don't want configure anything, use the "Invocation" stage. Only magic mapping and strict typing between objects and documents.

But if you need to make complex queries or map-reduce, it can be very dirty. This stage is usefull for RESTful app without GUI.

See full example in [unit test](https://github.com/Trismegiste/DokudokiBundle/blob/master/tests/DokudokiBundle/ReadmeExampleTest.php#L75)

```
// 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']);
```

### White Magic is for Lawful Good

[](#white-magic-is-for-lawful-good)

If you have a good model and the time to carefully alias classes in the database, use the "WhiteMagic" stage. There is automapping but without surprise, your model cannot turn into chaos. Any non-aliased class will generate an exception.

See full example in [unit test](https://github.com/Trismegiste/DokudokiBundle/blob/master/tests/DokudokiBundle/ReadmeExampleTest.php#L91)

```
// simple object
$doc = new \Some\Sample\Product('EF-85 L', 2000);
// persisting
$this->whitemagic->persist($doc);
// restoring with whitemagic repository
$restore = $this->whitemagic->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('product', $dump['-class']);  // here is the aliasing
$this->assertEquals('EF-85 L', $dump['title']);
$this->assertEquals(2000, $dump['price']);
```

### Hoodoo child

[](#hoodoo-child)

If you need to evolve the model above, you can use "Hoodoo" stage, a "WhiteMagic" stage mixed with some magic from "BlackMagic" stage. There is a safety net to prevent some "real" classes to become "fake" classes. This lowers the rate of WTF per minutes and you choose the level of magic.

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

[](#about-performance)

I have not fully tested this dbal but the hydration is the slowest part of this layer. For example, one document with 100 entities (think about a customer, with his addresses, past orders with products etc...) takes about 100 ms to be stored on a standard dual-core desktop without APC.

It is not very efficient but when you seek high performance, you can forget about ORM, ODM and so on.

FAQ
---

[](#faq)

### Is Symfony2 mandatory ?

[](#is-symfony2-mandatory-)

No, the DBAL can work in standalone mode. Anyway you miss a lot of features with forms and black magic stage. The full framework itself is not mandatory, only some components. And almost all unit tests don't need any symfony component. For example, you could easily make a provider for silex and pimple.

### What are the requirements ?

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

- PHP &gt;= 5.4
- PECL Mongo extension &gt;= 1.3
- The dev-master runs with Symfony2.3 and there are branches for 2.1 and 2.2

### 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.

### 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

### What about MongoDate ?

[](#what-about-mongodate-)

Any DateTime are converted into MongoDate and vice versa.

### I see you're using mongo types in your classes model, what about abstraction ?

[](#i-see-youre-using-mongo-types-in-your-classes-model-what-about-abstraction-)

Seriously, have you ever switch an app to another database ?

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

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

Fly, you fools

Why this silly name ?
---------------------

[](#why-this-silly-name-)

Well, I'm not good at finding names, that's why I tend to keep the most ridiculous than the most serious. It stands for Docu(ment) + doki to recall "dokidoki" (loosely means "excitment", sounds like heartbeats) in japanese. This one, I'm pretty sure it is unique ^\_^

###  Health Score

29

—

LowBetter than 59% of packages

Maintenance15

Infrequent updates — may be unmaintained

Popularity15

Limited adoption so far

Community7

Small or concentrated contributor base

Maturity64

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 ~109 days

Recently: every ~85 days

Total

9

Last Release

3941d ago

Major Versions

1.2 → 2.12013-12-10

PHP version history (3 changes)1.1PHP &gt;=5.3.8

1.2PHP &gt;=5.4

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 (31 commits)")

---

Tags

dbalSymfony2mongodb

### Embed Badge

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

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

###  Alternatives

[doctrine/dbal

Powerful PHP database abstraction layer (DBAL) with many features for database schema introspection and management.

9.7k578.4M5.6k](/packages/doctrine-dbal)[doctrine/doctrine-bundle

Symfony DoctrineBundle

4.8k241.3M3.3k](/packages/doctrine-doctrine-bundle)[doctrine/migrations

PHP Doctrine Migrations project offer additional functionality on top of the database abstraction layer (DBAL) for versioning your database schema and easily deploying changes to it. It is a very easy to use and a powerful tool.

4.8k204.8M440](/packages/doctrine-migrations)[doctrine/doctrine-migrations-bundle

Symfony DoctrineMigrationsBundle

4.3k177.9M537](/packages/doctrine-doctrine-migrations-bundle)[mongodb/mongodb

MongoDB driver library

1.6k64.0M546](/packages/mongodb-mongodb)[doctrine/mongodb-odm

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

1.1k23.3M302](/packages/doctrine-mongodb-odm)

PHPackages © 2026

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