es 生成过滤条件 php版

2 篇文章 0 订阅
<?php
namespace app\common\helper\tool\es;

/**
 * es 条件生成
 */
use app\common\helper\tool\Arrays;
class Cd
{
    /** @var string none */
    const NONE = 'none';

    /** @var string 等于 */
    const EQ = 'eq';

    /** @var string 包含 */
    const IN = 'in';

    /** @var string is not null */
    const HAS = 'has';

    /** @var string is null */
    const EXC = 'exc';

    /** @var string  大于 */
    const GT = 'gt';

    /** @var string  大于等于 */
    const GTE = 'gte';

    /** @var string  小于 */
    const LT = 'lt';

    /** @var string  小于等于 */
    const LTE = 'lte';

    const PRE_OP = [
        self::GT,
        self::GTE,
        self::LT,
        self::LTE,
        self::EQ,
        self::IN,
        self::HAS,
        self::EXC,
    ];

    const SINGLE_OP = [
        self::HAS,
        self::EXC,
    ];

    /** @var string and */
    const AND = '&&';

    /** @var string or */
    const OR = '||';

    /** @var string not */
    const NOT = '!';

    const PRE_TYPE = [
        self:: AND => 'filter',
        self:: OR => 'should',
        self::NOT => 'must_not',
    ];

    /** @var string 内部使用 */
    const BOOL = 'bool';

    /** @var string 元素 有这个key 说明该 元素是个bool 原始条件 */
    const COND_KEY = 'BS_ES_COND_KEY_&&||!';

    /** @var string 操作字段的键 */
    const K = 'KEY';

    /** @var string  条件值 */
    const V = 'VALUE';

    /**
     * 得到查询条件
          eg:
          $a_arr = [
              Cd:: AND => [
                  [Cd::K => 'id', Cd::V => [Cd::IN, [552646]]],
                      [
                          Cd::COND_KEY => [
                              Cd:: AND => [
                                [Cd::K => 'id', Cd::V => [Cd::GT, 552646]],
                                [Cd::K => 'id', Cd::V => [Cd::LT, 552646]]
                          ],
                      ]
                  ]
              ],
          ];
          $a_cond = Cd::getCondition($a_arr);
     *
     * @param array $a_param
     * @return array ['bool' => [ 'filter' =>[], 'must_not' => [], 'should' => [] ]]
     * @throws Exception
     */
    public static function getCondition(array $a_param)
    {
        $a_param = self::checkSimple($a_param);
        $a_cond = [];
        foreach ($a_param as $s_k => $a_v) {
            if (!key_exists($s_k, self::PRE_TYPE)) {
                throw new Exception('condition type is not supported');
            }
            $a_cond[self::PRE_TYPE[$s_k]] = self::makeArrCond($a_v);
        }
        return [
            self::BOOL => $a_cond
        ];
    }

    private static function makeArrCond(array $a_arr)
    {
        $a_tmp = [];
        foreach ($a_arr as $m_v) {
            if ($m_v[self::COND_KEY]) {
                $a_tmp [] = self::getCondition($m_v[self::COND_KEY]);
            } else {
                $m_val = is_array($m_v[self::V]) ? $m_v[self::V] : [$m_v[self::V]];
                $a_tmp [] = self::makeFieldCond($m_v[self::K], ...$m_val);
            }
        }
        return $a_tmp;
    }

    private static function makeFieldCond($s_k, $s_op, $m_val = null)
    {
        if ($m_val === null) {
            if (in_array($s_op, self::SINGLE_OP, true)) {
                $m_val = $s_op;
            } else {
                $m_val = $s_op;
                if (!is_array($m_val)) {
                    $s_op = self::EQ;
                } else {
                    $s_op = self::NONE;
                }
            }
        }
        if (!in_array($s_op, self::PRE_OP) ||
            !is_callable(__CLASS__ . '::' . $s_op) ||
            $m_val === null
        ) {
            throw new Exception('operation is not supported');
        }
        return self::$s_op($s_k, $m_val);
    }

    private static function checkSimple(array $a_param)
    {
        if (!self::hasPre($a_param)) {
            if (key_exists(self::K, $a_param)) {
                $a_param = [$a_param];
            }
            return [
                self:: AND => $a_param
            ];
        }
        return $a_param;
    }

    private static function hasPre(array $a_param)
    {
        return count(array_intersect(array_keys(self::PRE_TYPE), array_keys($a_param))) > 0;
    }

    private static function in($s_k, $m_val)
    {
        if (!Arrays::isList($m_val)) {
            throw new Exception('wrong value for operation - in');
        }
        return [
            'terms' => [
                $s_k => $m_val
            ]
        ];
    }

    private static function eq($s_k, $m_val)
    {
        return [
            'term' => [
                $s_k => $m_val
            ]
        ];
    }

    private static function gt($s_k, $m_val)
    {
        return self::range($s_k, $m_val, self::GT);
    }

    private static function gte($s_k, $m_val)
    {
        return self::range($s_k, $m_val, self::GTE);
    }

    private static function lt($s_k, $m_val)
    {
        return self::range($s_k, $m_val, self::LT);
    }

    private static function lte($s_k, $m_val)
    {
        return self::range($s_k, $m_val, self::LTE);
    }

    private static function range($s_k, $m_val, $s_op)
    {
        return [
            'range' => [
                $s_k => [
                    $s_op => $m_val
                ]
            ]
        ];
    }

    private static function has($s_k, $m_val)
    {
        return [
            'exists' => [
                'field' => $s_k
            ]
        ];
    }

    private static function exc($s_k, $m_val)
    {
        return [
            "bool" => [
                "must_not" => [
                    'exists' => [
                        'field' => $s_k
                    ]
                ]
            ]
        ];
    }
}

<?php
namespace app\common\helper\tool;
class Arrays
{
    /**
     * 验证数组是不是一个有值的标准list
     *
     * @param array $a_arr
     * @return bool
     */
    public static function isList(array $a_arr)
    {
        return array_keys($a_arr) === range(0, count($a_arr) - 1);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值