1. 程式人生 > >yii2 類似mongoose schema ,對mongodb 進行型別定義,以及強制轉換

yii2 類似mongoose schema ,對mongodb 進行型別定義,以及強制轉換

安裝完mongodb的外掛,就可以使用mongodb了,但是,在插入和更新mongodb的資訊的時候,active record 會因為沒有型別,

不能對欄位自動的強制轉換型別,下面是強制轉換型別

common\extensions\mongodb\IActiveRecord.php

<?php


namespace common\extensions\mongodb;
use Yii;
use yii\mongodb\ActiveRecord;
use common\extensions\mongodb\IActiveRecord\TypeConvert;
//use common\extensions\IActiveRecord;
/**
 * ActiveRecord is the base class for classes representing Mongo documents in terms of objects.
 *
 * @author Paul Klimov <
[email protected]
> * @since 2.0 */ class IActiveRecord extends ActiveRecord { public $_is_insert; /* public function __construct(){ $this->on(self::EVENT_AFTER_FIND,[$this,'afterFindData']); } public function afterFindData($event){ $event->name = 'aaaaaaaaaaaaa'; } */ # 1.將mongodb的時間轉換成字串 public static function getDateTime($dataOb,$format = 'Y-m-d H:i:s'){ if($dataOb->sec){ return date($format, $dataOb->sec); } return $dataOb; } # 2.將mongodb的時間轉換成字串 public function getDate($dataOb,$format = 'Y-m-d'){ if($dataOb->sec){ return date($format, $dataOb->sec); } return $dataOb; } # 3.返回屬性定義 public function attributes() { $attributes = []; $schema_columns = $this->schema_columns(); foreach($schema_columns as $column => $data){ $attributes[] = $column; } $attributes[] = '_id'; return $attributes; } # 4.在儲存前,強制進行型別轉換,依賴於 schema_columns()函式對collection的欄位型別定義。 public function beforeSave($insert) { if (parent::beforeSave($insert)) { # 得到欄位結構定義 $columns = $this->schema_columns(); # 得到當前的值。 $model_data = $this->getSchemaData(); # 如果是插入操作 if($insert == self::EVENT_BEFORE_INSERT){ $this->_is_insert = 1; # 生成當前的id 這個id 是當前通過 ids(colleciton)進行遞增得來。 $collection_name = $this->collectionName(); $this->_id = $this->increament($collection_name); }else{ } # 轉換型別 進行型別強制轉換。 $data = TypeConvert::forceChangeColumnsType($columns,$model_data,$this->_is_insert); # 將強制轉換型別後得到的值,重新進行賦值。 foreach($data as $k_col => $l_colo_val){ //echo $k_col; $this->$k_col = $l_colo_val; } return true; } else { return false; } } # 5.得到當前的屬性值 public function getSchemaData(){ $attributes = $this->attributes(); $arr = []; foreach($attributes as $attribute ){ $arr[$attribute] = $this->$attribute; } return $arr; } # 6.得到遞增id public function increament($tablename){ $coll = Yii::$app->mongodb->getCollection("ids"); $update = array('?inc'=>array('id'=>1)); $query = array('name'=>$tablename); $command = array( 'findandmodify'=>'ids', 'update'=>$update, 'query'=>$query, 'new'=>true, 'upsert'=>true ); $result = $coll->mongoCollection->db->command($command); $id = $result['value']['id']; Global $current_mongo_id; $current_id = (int)$id->value; return $id; } /* public static function find() { return Yii::createObject(IActiveQuery::className(), [get_called_class()]); } */ }

common\extensions\mongodb\IActiveRecord\TypeConvert.php

<?php
/**
 * @link http://www.yiiframework.com/
 * @copyright Copyright (c) 2008 Yii Software LLC
 * @license http://www.yiiframework.com/license/
 */

namespace common\extensions\mongodb\IActiveRecord;
use Yii;
use yii\mongodb\ActiveRecord;
/**
 * ActiveRecord is the base class for classes representing Mongo documents in terms of objects.
 *
 * @author Paul Klimov <
[email protected]
> * @since 2.0 */ class TypeConvert { public static $is_insert = 0; # 強制型別轉換 public static function forceChangeColumnsType($columns,$model_data,$is_insert=0){ $result = []; if($is_insert){ self::$is_insert = $is_insert; } foreach($columns as $column_name => $data){ //echo $column_name."<br/>"; //var_dump( $data); //echo "<br/>"; if($column_value = $model_data[$column_name]){ if(is_array($data)){ $dd = self::isColumnsArray($data); if( $dd == 'arrayColumns'){ $result[$column_name] = self::changeType($column_value,$data[0],1); }else if( $dd == 'arrayContainChild'){ foreach($column_value as $key=>$col_value){ $k = (String)(new \MongoId()); $result[$column_name][$k] = self::forceChangeColumnsType($data[0],$col_value); } }else{ $result[$column_name] = self::forceChangeColumnsType($data,$column_value); } }else{ $result[$column_name] = self::changeType($column_value,$data); } } } return $result; } # public static function isColumnsArray($data){ $not_numeric = 1; $is_string = 1; foreach($data as $k=>$v){ if(!is_numeric($k)){ $not_numeric = 0; } if(is_array($v)){ $is_string = 0; } } # 代表 僅僅一個數組,陣列中含有的是字串 if($not_numeric && $is_string){ return 'arrayColumns'; # 陣列中的變數,是陣列,也就是說裡面含有很多子陣列。 }else if($not_numeric && !$is_string){ return 'arrayContainChild'; } # 不是陣列型別 return 'notArray'; } # 轉換型別 public static function changeType($column_value,$type,$is_array=0){ if($is_array){ $arr = []; if(is_array($column_value)){ foreach($column_value as $key=>$v){ if(self::$is_insert){ $v = self::changeTypeData($v,$type); $k = (String)(new \MongoId()); $arr[$k] = $v; }else{ $v = self::changeTypeData($v,$type); $arr[$key] = $v; } } } return $arr; }else{ return self::changeTypeData($column_value,$type); } } public static function changeTypeData($column_value,$type){ $type = trim(strtolower($type)); if($type == 'int'){ $column_value = (int)$column_value; }else if ($type == 'string'){ $column_value = (String)$column_value; }else if ($type == 'string'){ $column_value = (String)$column_value; }else if ($type == 'float'){ $column_value = (float)$column_value; }else if ($type == 'datetime'){ $column_value = new \MongoDate(strtotime($column_value)); }else if ($type == 'date'){ $column_value = date('Y-m-d',strtotime($column_value)); $column_value = new \MongoDate(strtotime($column_value)); }else{ } return $column_value; } }


使用demo

1.定義active record:

<?php

namespace myapp\code\core\Erp\Sales\models;
use common\extensions\mongodb\IActiveRecord;
 //  use myapp\code\core\Erp\Sales\models\Mongocustomer;
class Mongocustomer extends IActiveRecord
{
	
	# 定義collection name
    public static function collectionName()
    {
        return 'mongo_customer';
    }

	# 定義collection 各個欄位的型別定義,在儲存前進行型別轉換
	public function schema_columns(){
		# 不要定義  _id
		return [
			
			'name' 			=> 'String',  # String型別
			'email' 		=> 'String',
			'address' 		=> 'String',
			'status' 		=> 'Int',		# Int型別
			'age'			=> 'Int',
			'active'		=> 'Int',
			'image'			=> [
				'media'			=> 'String',
				'created_at' 	=> 	'DateTime',	#時間型別
				'gallery'		=>  ['String'],	# 字串陣列
			],
			'price'	=> [
				'en_price' => 'float',  # float型別
				'fr_price' => 'float',
			],
			'created_at'	=> 'datetime',  # datetime型別
			'custom_option' => [
				[
					'name' 			=> 'String',
					'sort_order' 	=> 'Int',
					'is_required'	=> 'Int',
					'data'			=> [
						[
							'title' => [
								'en_title' => 'String',
								'fr_title' => 'String',
								'de_title' => 'String',
								'ru_title' => 'String',
							],
							'price' => 'Float',
							'sort_order' => 'Int',
							
							
							
						],
					],
				],
			]
		];
	}



}

2.呼叫  插入:
$Mongocustomer = new Mongocustomer();
		$Mongocustomer->name = 1;
		$Mongocustomer->created_at = '2015-01-01';
		$Mongocustomer->custom_option = [
			[
				'name' => 'color',
				'sort_order' => '2',
			],
			[
				'name' => 'size',
				'data' => [
					[
						'title' => [
							'en_title' => 'l',
							'fr_title' => 'l',
						],
						'price' => '12.22',
					],
					
					[
						'title' => [
							'en_title' => 'en_m',
							'fr_title' => 'fr_m',
						],
						'price' => '13.22',
					],
				],
			],
		];
		$Mongocustomer->image = [
			'media' 	=> 22,
			'gallery' 	=> [11,22,33,44,55],
		];
		$Mongocustomer->save();

儲存完成後,看結構:


可以看到結果被強制轉換了。

呼叫2:查詢
$data = Mongocustomer::find()->asArray()->all();
		foreach($data as $d){
			echo Mongocustomer::getDateTime($d['created_at']);
			echo "<br/>*********<br/>";
		}
		exit;

呼叫3:更新:

$dd = Mongocustomer::findOne(['_id'=>45]);
		$dd->name = 4444;
		$dd->save();
		var_dump($dd);
		exit;



結果:

1._id 是類似mysql的id遞增方式

2.如果一個定義的沒有key的陣列,會增加生成的mongodb的_id

3.定義的欄位都會強制轉換。

4.Mongocustomer::getDateTime($d['created_at']);  可以轉換時間格式。

相關推薦

yii2 類似mongoose schema mongodb 進行型別定義以及強制轉換

安裝完mongodb的外掛,就可以使用mongodb了,但是,在插入和更新mongodb的資訊的時候,active record 會因為沒有型別, 不能對欄位自動的強制轉換型別,下面是強制轉換型別 common\extensions\mongodb\IActiveRec

Python 裝飾器@函式進行功能擴充套件開閉原則

裝飾器可以對原函式進行功能擴充套件,但還不需要修改原函式的內容(開閉原則),也不需要修改原函式的呼叫。   demo.py(裝飾器,@): # 閉包 def w1(func): def inner(): # 對原函式進行功能擴充套件 pr

多尺度小波分解與重構matlab係數進行處理後構造C重構訊號1

自己要解決的問題是,用小波分解對時間序列進行多尺度分解,再分別對各系數進行預測,最後重構得到最後的預測結果。 因為對係數進行了新的處理,所以不能直接用waverec函式重構原始訊號,而需要先構造C,再用waverec函式重構原始訊號。 所以這裡主要解決的問題是

搭建jmeter測試環境定義效能測試流程web進行效能測試並上傳效能測試結果截圖

下載jmeter 官網地址:http://mirror.bit.edu.cn/apache//jmeter/ 啟動 雙擊上面批處理檔案。出現下圖 1 新增執行緒組 2 新增測試httpRequest 3 新增測試結果view 4 測試 5 檢視聚合報告 報告引數解釋 L

在Node中基於MongooseMongoDB進行增刪查改(CRUD)操作(一)

關鍵詞:mongodb安裝 mongoose使用 robomongo mongoose的CRUD操作 mongoose的查詢,增加,修改,刪除 工具介紹 MongoDB MongoDB是基於Javascript語言的資料庫,儲存格式是JSON,而N

使用MongooseMongoDB進行分頁

使用Mongoose對MongoDB進行分頁時,最簡單的用法是採用skip和limit var query = MyModel.find({}); query.count(function(err, count) {...}); query.skip(5)

.NET XML 進行創建增加刪除修改操作整理

res add post 做了 引用 nbsp order protected png 前言:   最近做了一個項目,程序A在一個服務器程序B在另一臺服務器,然而主程序A需要訪問程序B的圖片集文件夾下載到本服務器上,為了防止多次對Web Services進行調用,在主

hbuilder 連線夜神模擬器app進行模擬器除錯

分別啟動hbuilder 和夜神模擬器 對app進行模擬器除錯之前需要安裝好android-sdk tools 不會安裝的請看我的另一篇文章https://blog.csdn.net/qfxlw/article/details/83098051和https://blog.csdn.net/

java爬蟲之入門基礎 java讀取txt檔案字串進行操作後匯出txt檔案

相比於C#,java爬蟲,python爬蟲更為方便簡要,首先呢,python的urllib2包提供了較為完整的訪問網頁文件的API,再者呢對於摘下來的文章,python的beautifulsoap提供了簡潔的文件處理功能,這就成就了他爬蟲的優勢。 作為一名滿腦子要成為一名大牛的程式設計師小白來講,倒不是非要

spring boot MongoTemplate如何 mongodb 進行模糊查詢

以下為部分程式碼片段,供參考。 1: 程式碼片段1,用Pattern方式來實現 不區分大小寫的匹配(包括精確和模糊匹配) //完全匹配 Pattern pattern = Pattern.compile("^張$", Pattern.CASE_INSENSITIVE);

使用MD5線上加解密工具漢字進行加密得到不同的結果

1. 問題背景 使用相同的漢字字串進行MD5計算,有時候會遇到:使用不同的線上工具,得到不同的MD5計算結果。 2. 原因 出現這樣情況的原因,通常是因為不同的線上工具使用的對漢字的編碼方式不同。(如果還有其他原因,歡迎大家評論留言哈,本喵也很想知道~) 3. 驗證 用一個32位

React中專案進行打包後無法進用serve-s build進行修改路徑

前提:已經安裝進去了create-react-app。 今天早上就關於用命令: npm install -g serve 安裝了serve的包之後,用指令進行修改命令,就發現瞭如下的報錯: 看樣子那個serve的包已經安裝上去了,但是就是出現上面的報錯,在網上

定義一個日期類日期進行設定判斷是否為閏年

include using namespace std; class Date { public: void Set(int y,int m,int d); bool IsLeapYear();

整理的關於Javamongodb進行的CURD操作工具類及原始碼

package com.iceter.DataBase; import java.util.ArrayList; import java.util.List; import java.util.Map; import org.bson.Document; import org.bson.conversi

pymongo實現mongodb進行增刪改查操作

問題:使用python指令碼對伺服器上的mongodb某表的記錄進行增刪改查操作 解決方法: 可以使用pymongo模組實現對mongodb的增刪改查 limit: pymongo現在不能處理ss

java操作Mogodb資料庫資料庫進行增刪查改!

首先,我們在windows下安裝mongodb資料庫,安裝教程檢視上一篇文章: 程式碼如下: package io.mogo; import java.util.Map; import org.apache.commons.lang3.StringUtils; im

C#如何Mongodb進行增刪改查

MongoDB是一個基於分散式檔案儲存的資料庫。由C++語言編寫。旨在為WEB應用提供可擴充套件的高效能資料儲存解決方案。 它的特點是高效能、易部署、易使用,儲存資料非常方便。 如今MongoDB已經跟新到3.4版本,但是對於更新後的版本網上資料

要求從使用者輸入的多行文字中提取學生的姓名、學號及登入日期並封裝到 Student 類中作為類的私有屬性。建立一個 Student 型別的物件陣列學號進行 升序排序並輸出

/*從鍵盤輸入多行文字,格式如下:學生端名稱,姓名,班級名稱,學生 ID,註冊時間 姜濤,姜濤,,20092212232,2011-11-4 9:06:56 任超,任超,,20092212239,2011-11-4 9:06:56 楊陽,楊陽,,20092212302,20

要求從使用者輸入的多行文字中提取學生的姓名、學號及登入日期並封裝到 Student 類中作為類的私有屬性。建立一個Student型別的物件陣列學號進行 升序排序並輸出。

/*部落格網站設定了校驗密碼的規則,編寫方法檢驗一個字串是否是合法的密碼。規則如下:  密碼長度在8-16之間  密碼只能包含字母和數字  密碼必須存在至少2個數字 如果使用者輸入的密碼符合規則就顯示valid password,否則提示Invalid passwor

C# PHP 漢字進行MD5計算得到的結果不一樣

C# 計算32位小寫md5hash值演算法如下:public static string GetStrMd5_32X(string ConvertString) { MD5CryptoServiceProvider md5 = new