mongodb php 聚合 条件判断

<?php

namespace api\models;

class Mongo
{
    private $_manager;
    private $_host;
    private $_username;
    private $_password;
    private $_db;
    private $_port;

    public $lastInsertId = '';

    public function connect(array $config)
    {
        extract($config);
        $this->_host = $config['hostname'];
        $this->_username = $config['username'];
        $this->_password = $config['password'];
        $this->_db = $config['database'];
        $this->_port = $config['hostport'];
        $auth = $username ? $username . ':' . $password . '@' : '';
        $mongo = 'mongodb://' . $hostname . ':' . $hostport;

        $extra = [
            // 'db' => $config['database'],
            'authSource' => $config['authSource'] ?? $config['database'],
        ];
        if ($config['username']) {
            $extra['username'] = $config['username'];
        }
        if ($config['password']) {
            $extra['password'] = $config['password'];
        }
        return $this->_manager = new \MongoDB\Driver\Manager($mongo, $extra);
    }
    public function getDB()
    {
        return $this->_db;
    }
    public function setDB($db)
    {
        $this->_db = $db;
        return $this->_db;
    }
    public function getBulk()
    {
        return new \MongoDB\Driver\BulkWrite;
    }
    public function getWriteConcern()
    {
        return new \MongoDB\Driver\WriteConcern(\MongoDB\Driver\WriteConcern::MAJORITY, 1000);
    }

    /**
     * 插入数据
     * @param $db 数据库名
     * @param $collection 集合名
     * @param $document 数据 array格式
     * @return
     */
    public function insert($collection, $document)
    {
        $bulk = $this->getBulk();
        if ($this->isAssoc($document)) {
            if (!($document['_id'] ?? false) || !($document['_id'] instanceof \MongoDB\BSON\ObjectID)) {
                $document['_id'] = new \MongoDB\BSON\ObjectID;
            }
            $bulk->insert($document);
            $this->lastInsertId = $document['_id'];
        } else {
            foreach ($document as $val) {
                if (!($document['_id'] ?? false) || !($document['_id'] instanceof \MongoDB\BSON\ObjectID)) {
                    $val['_id'] = new \MongoDB\BSON\ObjectID;
                }
                $bulk->insert($val);
                $this->lastInsertId = $val['_id'];
            }
        }
        $res = $this->_manager->executeBulkWrite($this->_db . '.' . $collection, $bulk);
        if (empty($res->getWriteErrors())) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 删除数据
     * @param array $where
     * @param array $option
     * @param string $db
     * @param string $collection
     * @return mixed
     */
    public function delete($collection, $where = array(), $option = array())
    {
        $bulk = $this->getBulk();
        $bulk->delete($where, $option);
        return $this->_manager->executeBulkWrite($this->_db . $collection, $bulk);
    }

    /**
     * 更新数据
     * @param array  $where  类似where条件
     * @param array  $field  要更新的字段
     * @param bool   $upsert 如果不存在是否插入,默认为false不插入
     * @param bool   $multi  是否更新全量,默认为false
     * @param string $db     数据库
     * @param string $collection 集合
     * @return mixed
     */
    public function update($collection, $where = array(), $field = array(), $upsert = false, $multi = false)
    {
        if (empty($where)) {
            return 'filter is null';
        }
        $bulk = $this->getBulk();
        $write_concern = $this->getWriteConcern();
        if (isset($where['_id'])) {
            $where['_id'] = new \MongoDB\BSON\ObjectId($where['_id']);
        }
        $bulk->update($where, array('$set' => $field), array('multi' => $multi, 'upsert' => $upsert));
        $res = $this->_manager->executeBulkWrite($this->_db . '.' . $collection, $bulk, $write_concern);
        if (empty($res->getWriteErrors())) {
            return true;
        } else {
            return false;
        }
    }

    public function execute($collection, $where, $operator, $upsert = false, $multi = false)
    {
        $bulk = $this->getBulk();
        $write_concern = $this->getWriteConcern();
        if (isset($where['_id'])) {
            $where['_id'] = new \MongoDB\BSON\ObjectId($where['_id']);
        }
        $bulk->update($where, $operator, array('multi' => $multi, 'upsert' => $upsert));
        $res = $this->_manager->executeBulkWrite($this->_db . '.' . $collection, $bulk, $write_concern);
        if (empty($res->getWriteErrors())) {
            return true;
        } else {
            return $res->getWriteErrors();
        }
    }

    public function selectById($collection, $id, $options = array())
    {
        $filter = ['_id' => new \MongoDB\BSON\ObjectID($id)];
        $res = $this->query($collection, $filter, $options);
        foreach ($res as $item) {
            $data = $this->objToArray($item);
        }
        return $data;
    }

    public function query($collection, $filter, $options)
    {
        if ($filter['_id'] ?? false) {
            if (is_array($filter['_id'])) {
                $param = [];
                foreach ($filter['_id'] as $id) {
                    $param[] = new \MongoDB\BSON\ObjectID($id);
                }
                $filter['_id'] = [
                    '$in' => $param,
                ];
            } else {
                $filter['_id'] = new \MongoDB\BSON\ObjectID($filter['_id']);
            }
        }
        $query = new \MongoDB\Driver\Query($filter, $options);
        $res = $this->_manager->executeQuery($this->_db . '.' . $collection, $query);
        $data = array();
        foreach ($res as $item) {
            $tmp = json_decode(json_encode($item), true);
            if (isset($tmp['_id'])) {
                $tmp['_id'] = $tmp['_id']['$oid'];
            }
            $data[] = $tmp;
        }
        return $data;
    }

    /**
     * 执行MongoDB命令
     * @param array $param
     * @return \MongoDB\Driver\Cursor
     */
    public function command($param)
    {
        $cmd = new \MongoDB\Driver\Command($param);
        return $this->_manager->executeCommand($this->_db, $cmd);
    }

    private function isAssoc($arr)
    {
        return array_keys($arr) !== range(0, count($arr) - 1);
    }

    /**
     * 按条件计算个数
     *
     * @param string $collName 集合名
     * @param array $where 条件
     * @return int
     */
    public function count($collName, array $where)
    {
        $result = 0;
        $cmd = [
            'count' => $collName,
            'query' => $where,
        ];
        $arr = $this->command($cmd)->toArray();
        if (!empty($arr)) {
            $result = $arr[0]->n;
        }
        return $result;
    }
    public function objToArray($data)
    {
        return json_decode(json_encode($data), true);
    }
}

_id和id互转

$object_id = new \MongoDB\BSON\ObjectId($id)
$id = (string)$object_id

聚合查询

public static function aggregate()
{
    $mongo = new Mongo;
    $res = $mongo->connect(\Yii::$app->params['mongo']);
    $filter = [
        'name' => 'a',
    ];
    $option = [
        // 返回字段
        'projection' => [
            '_id' => 1,
            'name' => 1,
            'age' => 1,
        ],
        // 结果排序
        'sort' => [
            'age' => 1,
        ],
    ];
    $res = $mongo->query('test', $filter, $option);
    var_dump($res);
    $command = [
        'aggregate' => 'test',
        'pipeline' => [
            ['$match' => ['name' => 'a']],
            ['$sort' => ['age' => 1]],
            ['$group' => [
                '_id' => '$name',
                'id' => ['$last' => '$_id'],
                'name' => ['$last' => '$name'],
                'age' => ['$last' => '$age'],
            ]],
            ['$project' => [
                '_id' => 0,
                'id' => 1,
                'name' => 1,
                'age' => 1,
            ]],
            ['$limit' => 10],
        ],
        // 指针类型
        'cursor' => new \stdClass,
    ];
    $res = $mongo->command($command);
    foreach ($res as $key => $value) {
        $value->id = (string) $value->id;
        var_dump((array) $value);
    }
    die;
}

cond操作符

$command = [
    'aggregate' => 'test',
    'pipeline' => [
        ['$match' => ['name' => 'a']],
        ['$sort' => ['age' => 1]],
        ['$group' => [
            '_id' => '$data.key2',
            'name' => ['$last' => '$name'],
            'age' => ['$last' => '$age'],
            'data' => ['$last' => '$data'],
            'count' => [
                '$sum' => [
                    '$cond' => [
                        'if' => ['$eq' => ['$name', 'ddsx']],
                        'then' => 2,
                        'else' => 2,
                    ],
                ],
            ],
        ]],
        ['$project' => [
            '_id' => 0,
            'name' => 1,
            'age' => 1,
            'data' => 1,
            'count' => 1,
        ]],
        ['$limit' => 10],
    ],
    // 指针类型
    'cursor' => new \stdClass,
];

判断属性存在

exists
db.getCollection('台风山竹评论0').find({'lat':{'$exists': 'True'}})

正则匹配

// 存在搜索
public static function mongoRegx($search)
{
    return new \MongoDB\BSON\Regex("$search", 'i');
}
// 不存在搜索
public static function mongoRegxNotIn($search)
{
    return new \MongoDB\BSON\Regex("^((?!$search).)*$", 'i');
}

数组不包含

数组包含直接用正则搜索即可
数组不包含关键词使用$nin+正向的正则匹配即可

{"mail_field":{"$nin":[{"$regex":"aiai","$options":"i"}]}}

相关文章

此处评论已关闭