PHPackages                             itvisionsy/php-es-orm - 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. itvisionsy/php-es-orm

ActiveLibrary[Database &amp; ORM](/categories/database)

itvisionsy/php-es-orm
=====================

An ElasticSearch PHP ORM and Query Builder

v1.7.5(9y ago)33206.9k↓40%8[1 issues](https://github.com/itvisionsy/php-es-mapper/issues)1MITPHPPHP &gt;=5.4.0

Since Jun 17Pushed 8y ago2 watchersCompare

[ Source](https://github.com/itvisionsy/php-es-mapper)[ Packagist](https://packagist.org/packages/itvisionsy/php-es-orm)[ RSS](/packages/itvisionsy-php-es-orm/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (2)Versions (30)Used By (1)

ElasticSearch PHP ORM and Query Builder (es-mapper)
===================================================

[](#elasticsearch-php-orm-and-query-builder-es-mapper)

This is a simple ORM mapper for ElasticSearch for PHP.

[ElasticSearch DSL query builder for PHP](./query_builder_README.md).

Collaborators required
----------------------

[](#collaborators-required)

If you can join me in updating and maintaining this project, please send a message to

Requirements
------------

[](#requirements)

- PHP 5.4+
- Elasticsearch PHP SDK v&gt;=1 and &lt;2
- ElasticSearch server 1.6. ES2 is not tested, so use with care.

Installation
------------

[](#installation)

### Composer

[](#composer)

`composer require itvisionsy/php-es-orm`

### Manual download

[](#manual-download)

Head to the latest version [here](https://github.com/itvisionsy/php-es-mapper/releases/latest) then download using one download button.

How to use?
-----------

[](#how-to-use)

**For the Query Builder, [read this README instead](./query_builder_README.md)**

That is simple:

### Per index query:

[](#per-index-query)

1. Create a class extending the main query class (for general index use) .
2. Fill in the abstract methods. They are self-descriptive.
3. Use the created class `::find($type, $id)`, `::query($type, array $query =[])`, and `::all($type)`You will get a list of Model objects where you can object-property access to get all the info. i.e. `$model->name` to get the name property, ...

### Per type query

[](#per-type-query)

1. Create a class extending the type query class. OR create a class extending the main query class and implementing the `TypeQueryInterface` interface and use the `TypeQueryTrait` trait
2. Fill in the abstract methods. They are self-descriptive.
3. Use the methods: `::find($id)`, `::all()`, and `::query(array $query=[])`. You will get a list of Model objects the same way described above.

#### Please note

[](#please-note)

Methods' parameters are mapped to original elasticsearch methods and parameters as follows:

- `::find(scalar)` and `::find(scalar[])` methods are mapped to \[get\]( L167) and \[mget\]( L671) methods respectively.
- `::query` method is mapped to the \[search\]( L1002) method, and the $query param will be passed as is after appending the index and type parameters to it.

### Querying for data

[](#querying-for-data)

The query class is just a simple interface allows you to send DSL queries, or perform other ElasticSearch requests. The `::query()` method for example will expect to receive an assoc-array with a well-formed DSL query.

However, you can use the query builder to builder the query and get a well-formed DSL array out of it.

You can use a type-query query builder to build the query and execute it directly:

```
$result = TypeQuery::builder()
    ->where('key1','some value')
    ->where('key2',$intValue,'>')
    ->where('key3','value','!=')
    ->where('key4', ['value1','value2'])
    ->execute();
//$result is a \ItvisionSy\EsMapper\Result instance
```

Or you can use a generic query builder to build the query then you can modify it using other tools:

```
//init a builder object
$builder = \ItvisionSy\EsMapper\QueryBuilder::make();

//build the query using different methods
$query = $builder
                ->where('key1','some value') //term clause
                ->where('key2',$intValue,'>') //range clause
                ->where('key3','value','!=') //must_not term clause
                ->where('key4', ['value1','value2']) //terms clause
                ->where('email', '@hotmail.com', '*=') //wildcard search for all @hotmail.com emails
                ->sort('key1','asc') //first sort option
                ->sort('key2',['order'=>'asc','mode'=>'avg']) //second sort option
                ->from(20)->size(20) //results from 20 to 39
                ->toArray();

//modify the query as you need
$query['aggs']=['company'=>['terms'=>['field'=>'company']]];

//then execute it against a type query
$result = TypeQuery::query($query);
//$result is a \ItvisionSy\EsMapper\Result instance
```

Please refer to [this file](./query_builder_README.md) for more detailed information.

Retrieving results
------------------

[](#retrieving-results)

The returned result set implements the ArrayAccess interface to access specific document inside the result. i.e.

```
$result = SomeQuery::all();
```

You can then get a document like this:

```
$doc = $result[1]; //gets the second document
```

Or you can use the dot notation like that:

```
$result->fetch('hits.hits.0'); //for any absolute access

```

Accessing document data
-----------------------

[](#accessing-document-data)

On the model object, you can access the results in many ways:

1. using the object attribute accessor `$object->attribute`
    - if the attribute starts with underscore (\_) then it will try to fetch it first from the meta information, then the attributes, and then from the internal object properties.
    - if the attribute starts with two underscores (\_\_) then it will try to fetch first from the internal object properties, then attributes, then meta.
    - if not precedence underscores, then it will try to fetch from the attributes, then meta, then internal object properties.
2. using the `$object->getAttributes()[attribute]`, as the getAttributes() will return the document data as an array (first level only).
3. using the `$object->getAttributes($attribute1, $attribute2, ...)` which will return a single (or array) value\[s\] depending on the requested attributes

Creating new documents
----------------------

[](#creating-new-documents)

Either way will work:

1. Use the index query static method

    ```
    IndexQuery::create(array $data, $type, $id=null, array $parameters=[])
    ```
2. Use the type query static method:

```
TypeQuery::create(array $data, $id=null, array $parameters=[])
```

Updating a document
-------------------

[](#updating-a-document)

You can update an already indexed document by:

1. Either *Re-indexing* a document with the same type and id, OR
2. Or `update(array $data, array $parameters=[])` method on the model's object:

```
TypeQuery::find(1)->update(['new_key'=>'value','old_key'=>'new value'],[]);
```

Deleting a document
-------------------

[](#deleting-a-document)

The same way you can update a document, you can delete it:

1. Calling the static method `::delete($type, $id)` on the index query
2. Calling the method `->delete()` on model's object.

Adding extra methods
--------------------

[](#adding-extra-methods)

You may need to add extra custom methods like `top($numOfDocs)` or anything else. To do so, you need to create the method name you wish as protected in the query sub-class. The name should be prefixed with \_ (i.e. `_top`) then, you can either

- Call it prefixed with `get`, so to call the `_top(500)` method, just call `getTop(500)` and it will be mapped as public static and as public.
- Override the `_allowPublicAccess` static protected method to add extra methods to expose. Please note that when overriding, don't forget to merge with the parent results not to lose the old ones:

    ```
    protected _allowPublicAccess(){
        return array_merge(parent::_allowPublicAccess(), ['top','any',...]);
    }
    ```

    This way you will save the allowed methods from the parent.

### Extending the Model class

[](#extending-the-model-class)

You can extend the Model class easily. Just extend it! In case you were using the namespaces, you can set the models namespace in the query class by overriding the modelNamespace public method. This method should return a string ending with
After that, you need to call the `->setModelClass($class)` on the query result object.

Examples
--------

[](#examples)

Please check [tests/](/tests) folder. Basically, the case1.php is the main file.

```
\
|
+-- TestsIndexQuery (TestsIndexQuery.php)   Main index query class.
|   |                                       Maps results to \Models\ namespace.
|   |
|   +-- \FooTypeQuery (FooTypeQuery.php)    Type index query class.
|   |
|   +-- \BarTypeQuery (BarTypeQuery.php)    Type index query class.
|
|-- Models\
    |
    +-- Foo (FooMode.php)                   Foo model class
    |
    +-- Bar (BarModel.php)                  Bar model class

```

License
-------

[](#license)

This code is published under [MIT](LICENSE) license.

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance19

Infrequent updates — may be unmaintained

Popularity42

Moderate usage in the ecosystem

Community16

Small or concentrated contributor base

Maturity69

Established project with proven stability

 Bus Factor1

Top contributor holds 98.8% 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 ~24 days

Recently: every ~91 days

Total

28

Last Release

3343d ago

### Community

Maintainers

![](https://www.gravatar.com/avatar/11ac511b34acf3f7e9a138d3b1a0a868303b376ab991bb176e8ea474857a0e57?d=identicon)[mhh1422](/maintainers/mhh1422)

---

Top Contributors

[![mhh1422](https://avatars.githubusercontent.com/u/499764?v=4)](https://github.com/mhh1422 "mhh1422 (80 commits)")[![showerst](https://avatars.githubusercontent.com/u/1761520?v=4)](https://github.com/showerst "showerst (1 commits)")

---

Tags

builderdata-mapperelasticelasticsearchormphpquery-builder

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/itvisionsy-php-es-orm/health.svg)

```
[![Health](https://phpackages.com/badges/itvisionsy-php-es-orm/health.svg)](https://phpackages.com/packages/itvisionsy-php-es-orm)
```

###  Alternatives

[elasticquent/elasticquent

Maps Laravel Eloquent models to Elasticsearch types.

1.4k945.1k2](/packages/elasticquent-elasticquent)[pdphilip/elasticsearch

An Elasticsearch implementation of Laravel's Eloquent ORM

145360.2k4](/packages/pdphilip-elasticsearch)[basemkhirat/elasticsearch

Laravel, Lumen and Native php elasticseach query builder to build complex queries using an elegant syntax

402312.0k](/packages/basemkhirat-elasticsearch)[sleimanx2/plastic

Plastic is an Elasticsearch ODM and mapper for Laravel. It renders the developer experience more enjoyable while using Elasticsearch by providing a fluent syntax for mapping , querying and storing eloquent models.

508141.9k1](/packages/sleimanx2-plastic)[iverberk/larasearch

Elasticsearch enabled Eloquent models

22415.4k](/packages/iverberk-larasearch)[isswp101/elasticsearch-eloquent

Elasticsearch functionality like Laravel Eloquent models.

11220.7k](/packages/isswp101-elasticsearch-eloquent)

PHPackages © 2026

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