coding-socks/reloquent

Redis和PHP的对象映射,更多功能。

v0.1.0 2022-01-27 20:06 UTC

This package is auto-updated.

Last update: 2024-09-28 01:48:07 UTC


README

Redis + Eloquent = Reloquent

介绍

Reloquent是一个 实验性的对象关系映射器(ORM),可以让您愉快地与Redis进行交互。除了管理Redis散列外,Reloquent模型还允许您使用RediSearch搜索记录。

这个库受到了Redis OM的极大启发。

定义一个模型

use CodingSocks\Reloquent\Model;

class Movie extends Model
{
    protected $schema = [
        'title' => ['type' => 'string', 'textSearch' => true],
        'year' => ['type' => 'number'],
        'directors' => ['type' => 'array'],
    ];
}

创建一个新模型并保存它

$movie = new Movie()
$movie->title = "Alice in Wonderland";
$movie->year = 1951;
$movie->directors = ['Clyde Geronimi', 'Wilfred Jackson', 'Hamilton Luske'];
$movie->save()

搜索模型

Movie::query()
    ->where('title', 'matches', ['Alice', 'Wonderland'])
    ->where('year', '<=', 2000)
    ->where('directors', 'contains', ['Clyde Geronimi', 'Hamilton Luske'])
    ->get();

入门指南

首先,创建一个Laravel项目。

composer create-project laravel/laravel example-app

一旦您有了 composer.json,将其添加到其中

composer require coding-socks/reloquent

您需要Redis,最好有RediSearch。最简单的方法是设置一个免费的Redis Cloud实例。但是,您也可以使用Docker

docker run -p 6379:6379 --name reloquent redislabs/redismod:preview

将Redis配置为数据库

打开 config/database.php 并添加一个基于Redis的驱动连接。

    // [...]

    'connections' => [

        // [...]

        'redis' => [
            'driver' => 'redis',
            'connection' => 'default',
            'data_structure' => 'hash',
        ],

        // [...]

    ],
    
    // [...]

其余的都将来自您的redis配置。

创建、获取、更新和删除模型

当RediSearch可用来管理索引时,模型需要schema。当只管理HASH或JSON数据类型时,则不是必需的。

<?php

namespace App\Models;

use CodingSocks\Reloquent\Model;

class Movie extends Model
{
}

完成后,我们就可以进行一些简单的查询。

<?php

use App\Models\Movie;

// Create

$movie = new Movie();
$movie->title = "Matrix";
$movie->year = 1999;
$movie->directors = ['Lana Wachowski', 'Lilly Wachowski'];
$movie->save();

// Fetch

$movie = Movie::find('01FTDC7A39ZGTCNH2D3DN5RPKR');

// Update

$movie = Movie::find('01FTDC7A39ZGTCNH2D3DN5RPKR');
$movie->title = "The Matrix";
$movie->save();

// Delete

$movie = Movie::find('01FTDC7A39ZGTCNH2D3DN5RPKR');
$movie->delete()

使用RediSearch

查询模型

当未定义schema时,Reloquent将尝试根据查询值的类型猜测字段的类型。在大多数情况下,为每个模型定义一个schema更好。

<?php

namespace App\Models;

use CodingSocks\Reloquent\Model;

class Movie extends Model
{
    protected $schema = [
    'title' => ['type' => 'string', 'textSearch' => true],
    'year' => ['type' => 'number'],
    'directors' => ['type' => 'array'],
];
}

迁移定义了模型的索引。它是独立管理的,以便可以单独更改它

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateMoviesTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('movies', function (Blueprint $table) {
            $table->string('title')->textSearch();
            $table->integer('year');
            $table->array('directors');
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('movies');
    }
}

运行迁移后,我们可以查询新创建的索引。

Movie::query()
    ->where('title', 'matches', ['Alice', 'Wonderland'])
    ->where('year', '<=', 2000)
    ->where('directors', 'contains', ['Clyde Geronimi', 'Hamilton Luske'])
    ->get();

分页

尚不支持。

计数

尚不支持。

使用RedisJSON

尚不支持。

注意事项

配置

Redis配置中的prefix被忽略。

PhpRedis

\Redis::OPT_REPLY_LITERAL被设置为true,对于PhpRedis,它禁用了rawCommand的基本字符串到布尔值的转换。如果您在应用程序中使用rawCommand,请注意这一点。

缺失的记录

Redis以及Reloquent都不会区分缺失和null。Redis中的缺失字段返回null,缺失键也返回null。因此,如果您获取一个不存在的实体,它将愉快地返回一个满是null的实体。

$movie = Movie::find('DOES_NOT_EXIST');
$movie->title; // null
$movie->year; // null
$movie->directors; // null

$exists = Movie::exists($movie->id) // false

这是因为它Redis不区分缺失和null。您可能有一个全是null的实体。或者您可能没有。Redis不知道您的意图是什么,所以在您调用find时总是返回某些内容

排序

由于RediSearch的限制,只考虑最新的orderBy。已经有一个问题要求实现多个排序。

生产就绪性

此项目仍处于alpha阶段。在这个阶段,公共API可能每天会多次更改。

当功能集涵盖了大多数Eloquent方法时,将考虑beta版本。

贡献

欢迎任何类型的贡献;从功能、错误修复、文档改进、反馈、问题。虽然GitHub使用“问题”一词,但您可以随时为这些问题中的任何一个打开GitHub问题。