andsalves/doctrine-elastic

Elasticsearch Doctrine 适配器


README

针对 Elasticsearch 的自定义 Doctrine 库。

Build Status Coverage Status Scrutinizer Code Quality

最新稳定版本:v1.3.1(支持 Elasticsearch 2.x 或 5.x)

在 Elasticsearch 2.4.1/5.1/5.5 - PHP 5.6/7.0 上进行测试

此库不再积极维护

入门

创建一个工作的 ElasticEntityManager

请参阅 https://github.com/andsalves/doctrine-elastic/blob/master/docs/creating-an-elastic-entity-manager-instance.md

创建一个工作的 DoctrineElastic 实体

就像 Doctrine 一样,我们需要在我们的实体中设置一些注解,以下是一个例子

<?php
namespace DoctrineElastic\Entity;

use Doctrine\ORM\Mapping as ORM;
use DoctrineElastic\Mapping as ElasticORM;

/**
 * @author Ands
 *
 * @ElasticORM\Type(name="foo_type", index="foo_index")
 * @ORM\Entity
 */
class FooType {

    /**
     * @var string
     *
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @ElasticORM\MetaField(name="_id")
     * @ORM\Column(name="_id", type="integer")
     */
    public $_id;

    /**
     * @var int
     *
     * @ElasticORM\Field(name="custom_numeric_field", type="integer")
     */
    private $customNumericField;
    
    /**
     * @var string
     * 
     * Below: Use 'string' for elasticsearch 2.x and 'keyword' for elasticsearch 5.x+
     * @ElasticORM\Field(name="custom_field", type="string")
     */
    private $customField;
    
    /**
     * @var array
     *
     * @ElasticORM\Field(name="custom_nested_field", type="nested")
     */
    private $customNestedField = [];
    
    /**
     * @return int
     */
    public function getCustomNumericField() {
        return $this->customNumericField;
    }
    
    /**
     * @param int $customNumericField
     * @return FooType
     */
    public function setCustomNumericField($customNumericField) {
        $this->customNumericField = $customNumericField;
        return $this;
    }
    
    /**
     * @return string
     */
    public function getCustomField() {
        return $this->customField;
    }
    
    /**
     * @param string $customField
     * @return FooType
     */
    public function setCustomField($customField) {
        $this->customField = $customField;
        return $this;
    }
    
    /**
     * @return array
     */
    public function getCustomNestedField() {
        return $this->customNestedField;
    }
    
    /**
     * @param array $customNestedField
     * @return FooType
     */
    public function setCustomNestedField($customNestedField) {
        $this->customNestedField = $customNestedField;
        return $this;
    }
}

此实体代表 Elasticsearch 中的一个名为 'foo_type' 的类型,属于名为 'foo_index' 的索引。注意类注解 @ElasticORM\Type 有这些定义。属性注解 @ElasticORM\Field 代表 'foo_type' 类型内部文档的 _source 字段。@ElasticORM\MetaField 注解代表元字段,如 _id。@ElasticORM\MetaField _id 是实体必需的,并且必须是公共属性。

只有带有 @ElasticORM\Field 注解的属性将被视为文档字段。在 Elasticsearch 中,文档列名将是类属性中 @ElasticORM\Field 注解的 'name' 属性,就像 'type' 注解属性的属性。

插入文档

使用此库,通过 ElasticEntityManager 进行 CRUD 操作非常简单。假设您在变量 $elasticEntityManager 中有一个 ElasticEntityManager 实例

$newFoo = new DoctrineElastic\Entity\FooType(); // Or wherever be your entity
$newFoo->setCustomNumericField(1234);
$newFoo->setCustomField('Test Value');
$newFoo->setCustomNestedField(['some_value' => 'Some Value', 'whatever' => 'Whatever']);

$elasticEntityManager->persist($newFoo); // Persisting entity...
$elasticEntityManager->flush(); // And flushing... Oh God, just like Doctrine!
注意 1

如果尚未存在,索引和类型将自动创建,以及它们的映射。

注意 2

默认情况下,可分析字段的映射将是 not_analyzed(索引='not_analyzed')。DoctrineElastic 就是为此而设计的。但是,如果您喜欢默认的 analyzed 字段,您可以使用 'index' @ElasticORM\Field 注解属性来更改它。例如,@ElasticORM\Field(name='mad_field', type='string', index='analyzed')。注意:当您这样做时,使用 ElasticEntityManager 搜索文档不保证,因为一次可能无法匹配精确值。

注意 3

DoctrineElastic 不接受事务(尚不支持)。您将在 ElasticEntityManager 中找到一个可用的 'beginTransaction' 方法,但它不起作用。它在那里是因为 ElasticEntityManager 实现了 Doctrine 的 EntityManagerInterface。这种情况也适用于一些其他方法。

注意 4

就像在 Doctrine 一样,提交后,实体将填充 _id 字段。如果您持久化一个非空的 _id 字段的实体,DoctrineElastic 将搜索一个文档进行更新,如果不存在,则使用提供 _id 创建。

查找文档

如果您熟悉 Doctrine,这将非常简单直观

$myFoo = $elasticEntityManager->getRepository(DoctrineElastic\Entity\FooType::class)->findOneBy(['customNumericField' => 1234]);

if (!is_null($myFoo)) {
    print 'Yes, I found it!';
} else {
    print 'Nothing here';
}
注意 1

您也可以使用 findBy 和 findAll 方法。

注意 2

无论索引和类型是否存在于您的 Elasticsearch 中,都没有关系。如果不存在,则不返回任何文档,也不会抛出异常。

注意 3

要按 _id 搜索,请使用 $elasticEntityManager::getReference 或 $elasticEntityManager::find(它们在 ElasticEntityManager 中是等效的)。

删除文档

$myFoo = $elasticEntityManager->getRepository(DoctrineElastic\Entity\FooType::class)->findOneBy(['customNumericField' => 1234]);

if (!is_null($myFoo)) {
    // Let's delete this one
    $elasticEntityManager->remove($myFoo);
    $elasticEntityManager->flush(); // Deleted :)
} else {
    print 'Nothing to remove';
}

使用 Query Builder

请参阅此功能的测试示例:https://github.com/andsalves/doctrine-elastic/blob/master/tests/DoctrineElastic/Tests/ElasticEntityManagerTest.php

父子关系

请将此功能的测试作为良好示例:https://github.com/andsalves/doctrine-elastic/blob/master/tests/DoctrineElastic/Tests/ParentChildTest.php

DoctrineElastic 与应用端的关系

你可以模拟关系型数据库的关系,但显然会损失性能。DoctrineElastic 作为内部功能开发具备这一特性,但不建议使用——如果你需要复杂的关系,你应该使用关系型数据库。如果你真的想用这个库实现类似的关系,请联系我寻求帮助。

如有疑问,请通过以下邮箱联系我:ands.alves.nunes@gmail.com
请随时提出问题或发起代码合并请求。