MongoDB中数据的替换方法实现类Replace()函数功能详解

来源:脚本之家  责任编辑:小易  

mongodb中有聚合函数,可以使用聚合函数查询最值。案例代码://计算时间编号expo

近日接到一个开发需求,因业务调整,需要DBA协助,将MongoDB数据库中某集合的进行替换。例如我们需要将集合A中B字段中,有关《美好》的字符替换为 《非常美好》。个人感觉这个需求如果是在SQL Server 或MySQL 数据库上处理是小菜一碟,如果是针对MongoDB数据,可能要费神了。

1.常见关系数据数据库中的替换函数

我刚换了电脑,装的是win8.164位系统,我装了PHP和apache,都是32位的,我在虚拟机上装

在SQL Server数据库中,我们用Replace函数来实现字符的替换。

js把mongodb里面的数据以json形式输出需要依赖外部js:1、db.js从db获取数据

语法

可以,并且有这些优势1、使用JSON风格语法,易于掌握和理解:MongoDB使用JSON的变种B

REPLACE ( ''string_replace1'' , ''string_replace2'' , ''string_replace3'' )

在MongoDB中,文档是对数据的抽象,它被使用在Client端和Server端的交互中。所有的Cl

参数

''string_replace1''

不想结婚有以下这几点原因,一可能不够深爱,对方不适合结婚,二经济问题,没钱买婚房婚车,装修房子,三,年纪还小,想再拖几年,四怕婆媳关系处不好,五女友没怀孕不想结婚,怕婚后生不出孩子,暂时想到这么多,更多情感话题可以关注我,新面纱

待搜索的字符串表达式。string_replace1 可以是字符数据或二进制数据。

育儿是一件综合了所有社会学科,汇集了各种问题,同时也提供了各种探索机会和创造了无限可能的,非常美好美妙的一件事情。如果说用海来形容,确实可以。因为“海纳百川”,育儿路上,只有想不到的,而没有遇不到的。从个人生涯成长的角度,这正是提供了一个“有容乃大”的机会。不断的发现问题,我们有了自己的探索能力、分析能力。不断的分析问题,我们有了自己的思考能力、挑战能力、策划能力。不断的解决问题,我们有了自己的学习能力、行动能力、总结能力。我们在这个过程中不断增加自己的头脑中的突触连接,促进了大脑的再次发育。所以,对每一个即将成为父母或者是已经父母的我们来说,育儿是海,也是一个新的领域和空间,可以遇见未知的自

''string_replace2''

卧室在人们的生活中可是起到了举足轻重的作用,因为生命中的头等大事—睡觉就是在这里进行的!但是,您是否有听说床头朝正西睡觉经常会做噩梦?床头朝正西的很多老人身体会不好?床头朝西又有什么科学根据呢?地球是在不停地公转和自转中,地球的自转是由西向东自转床头朝正西,睡觉时和地球的自转方向相反,自然地,在同等时间里,您睡觉时补充的体能肯定会比其他方位的差。就像我们坐车,您如果有注意,您会发现,你如果坐在与车子前进的方向相反的位置,您肯定会感觉比较累。特别是会晕车的人,这种效果更明显。因为您要拿出一部分的体力来抵消相对运动产生的动能的消耗。床头朝正西的道理和这是一样的。床头朝西,睡久人会出现什么反应?1、

待查找的字符串表达式。string_replace2 可以是字符数据或二进制数据。

国足获胜,一要感谢里皮,二要感谢队员的不放弃,还要感谢球迷1:0击败韩国之后,很多中国球迷都说,12强赛有这场胜利足矣,如今,中国队在倒数第二轮又击败了乌兹比克,球迷无疑更加兴奋。是什么让国足打破宿命呢?首先要感谢的是里皮,其实,这场比赛里皮下半场的调整并不是很成功,在从433改为343之后,球队的进攻反而出现了问题,但中国队队员没有放弃,这一点是最重要的,这其实也是里皮带来的,他带给中国队的,绝不仅仅是技战术,更重要的是球员的精神面貌——信心和斗志。很多人都说,里皮如果从一开始就执教12强赛,中国队说不定已经开始庆祝出线了,确实有这种可能,但我们不是在后悔,真正想表达的是:中国足球其实不必妄

''string_replace3''

替换用的字符串表达式。string_replace3 可以是字符数据或二进制数据。

 例如将 字符串 SQL Server 数据库 中的  SQL Server 替换为 MongoDB。

实现语句如下:

在MySQL数据库中语法类似。

2.在MongoDB中实现替换方法

很可惜,到目前为止还没有找到类似SQL Server的替换函数,那么我们怎么去实现文档中的数据替换呢?特别是集合中的文档数量比较大时。

假设现在有用户信息文档,如下。注意其中有联系地址。

{ "_id" : ObjectId("5c77e5f85f53771b74bc87e0"), "username" : "hanmeimei", "email" : "123456@126.com", "tel" : 7891233, "addresses" : { "provice" : "山东省", "city" : "菏泽市鄄城县曹集镇", "stree" : "武状元街道28号" } }, /* 2 createdAt:2019/2/28 下午9:45:28*/ { "_id" : ObjectId("5c77e5f85f53771b74bc87df"), "username" : "Lily", "email" : "123456@126.com", "tel" : 123455, "addresses" : [ { "provice" : "河南省", "city" : "郑州市登封县李集镇", "stree" : "少林街道28号" } ] }, /* 3 createdAt:2019/2/28 下午9:45:28*/ { "_id" : ObjectId("5c77e5f85f53771b74bc87de"), "username" : "Lily", "email" : "123456@126.com", "tel" : 123455, "addresses" : { "provice" : "山东省", "city" : "菏泽市定陶县曹集镇", "stree" : "武状元街道28号" } }, /* 4 createdAt:2019/2/28 下午9:45:28*/ { "_id" : ObjectId("5c77e5f85f53771b74bc87dd"), "username" : "jack", "email" : "123456@126.com", "tel" : 123455, "addresses" : { "provice" : "山东省", "city" : "菏泽市定陶县", "stree" : "武状元街道28号" } }

现在因为行政区域划分,将 菏泽市定陶县划为定陶县区。那么怎么进行批量修改呢? MongoDB中没有Replace。

Update,也不好写代码。

最终.......我们还是找到了一个方法。

大家是先看看执行的代码及实现的结果。

db.user.find({'addresses.city':{'$regex': /菏泽市定陶县/ }}).forEach( function(item) { var tmp = String(item.addresses.city) tmp = tmp.replace('菏泽市定陶县','菏泽市定陶县区') if (tmp == null){ print(item.addresses.city) } item.addresses.city = tmp ; db.user.save(item); } );

  

 

执行后,再次查看数据,结果如下:

/* 1 createdAt:2019/2/28 下午9:45:28*/ { "_id" : ObjectId("5c77e5f85f53771b74bc87e0"), "username" : "hanmeimei", "email" : "123456@126.com", "tel" : 7891233, "addresses" : { "provice" : "山东省", "city" : "菏泽市鄄城县曹集镇", "stree" : "武状元街道28号" } }, /* 2 createdAt:2019/2/28 下午9:45:28*/ { "_id" : ObjectId("5c77e5f85f53771b74bc87df"), "username" : "Lily", "email" : "123456@126.com", "tel" : 123455, "addresses" : [ { "provice" : "河南省", "city" : "郑州市登封县李集镇", "stree" : "少林街道28号" } ] }, /* 3 createdAt:2019/2/28 下午9:45:28*/ { "_id" : ObjectId("5c77e5f85f53771b74bc87de"), "username" : "Lily", "email" : "123456@126.com", "tel" : 123455, "addresses" : { "provice" : "山东省", "city" : "菏泽市定陶县区曹集镇", "stree" : "武状元街道28号" } }, /* 4 createdAt:2019/2/28 下午9:45:28*/ { "_id" : ObjectId("5c77e5f85f53771b74bc87dd"), "username" : "jack", "email" : "123456@126.com", "tel" : 123455, "addresses" : { "provice" : "山东省", "city" : "菏泽市定陶县区", "stree" : "武状元街道28号" } }

集合文档中addresses.city中的'菏泽市定陶县' 全部被 '菏泽市定陶县区' 替换,符合设计要求。

3.知识补充与回顾

(1)作为一个数据库,MongoDB有一个很大的优势—它使用js管理数据库,所以也能够使用js脚本进行复杂的管理。MongoDB自带JavaScript shell,可在shell中使用命令行与MongoDB进行交互。shell是一个功能完备的JavaScript解释器,可运行任意JavaScript程序。

mongodb 的shell是javascript实现的,如果直接使用js实现相应的功能则显得很直观和简便。比如我们对一些数据进行 统计计算,除了使用mapreduce和aggreate框架之外,直接使用js也是很好的选择。还有一些批处理,数据同步都可以使用js

例如将集合中所有的文档,打印出来--  db.collectionname.find().forEach(printjson)。

注意:在上面演示的MongoDB替换字符的脚本,都在mongodb shell 和 nosqlbooster 工具里面验证过,没有问题。但是相同的代码在mongodb shell中要注意格式要求,最好要符合Javascript 格式要求,否则,可能报错,如:E QUERY    [thread1] SyntaxError: missing ; before statement @(shell):1:138

(2)forEach:MongoDB数据库使用游标返回find的执行结果。客户端对游标的实现通常能够对最终结果进行有效的控制。可以限制结果的数量,略过部分结果,根据任意键按任意顺序的组合对结果进行各种排序,或者是执行其他一些强大的操作。游标有一个重要的迭代函数---cursor.forEach(回调函数),允许我们自定义回调函数来逐个处理每个单元.

(3)$regex :正则表达式是使用单个字符串来描述、匹配一系列符合某个句法规则的字符串。MongoDB 使用 $regex 操作符来设置匹配字符串的正则表达式。

更多关于MongoDB中数据的替换方法实现的方法请查看下面的相关链接

扩展阅读,根据您访问的内容系统为您准备了以下内容,希望对您有帮助。

mongodb replace函数 只能替换一条吗

javascript的replace函数在替换数据时,默认只替换第一个。 如果在替换的时候加上: / 替换内容 /g 就能实现全部替换 示例: 比如说把“a”全部替换为“b” var strValue="administrator" strvalue = strvalue.replace(/a/g,"b");本回答被提问者采纳

如何实现mongodb中的sum汇总操作?

首先在本地机器上安装并设置MongoDB服务。

从Mongo网站上下载MongoDB,解压到本地目录,比如C:>Mongo

在上一个文件夹内创建数据目录。比如:C:\Mongo\Data

如果数据文件存放在其他地方,那么在用mongod.exe命令启动MongoDB时,需要在命令行加参数—-dbpath

启动服务

MongoDB提供了两种方式:mongod.exe以后台进程启动;mongo.exe启动命令行界面,可做管理操作。这两个可执行文件都位于Mongo\bin目录下;

进入Mongo安装目录的bin目录下,比如:C:> cd Mongo\bin

有两种启动方式,如下:

mongod.exe –dbpath C:\Mongo\data

或者

mongod.exe –config mongodb.config

mongodb.config是Mongo\bin目录下的配置文件,需要在此配置文件中指定数据目录(比如,dbpath= C:\Mongo\Data)的位置。

连接到MongoDB,到这一步,mongo后台服务已经启动,可以通过http://localhost:27017查看。 MongoDB启动运行后,我们接下来看它的聚合函数。

实现聚合函数

在关系数据库中,我们可以在数值型字段上执行包含预定义聚合函数的SQL语句,比如,SUM()、COUNT()、MAX()和MIN()。但是在MongoDB中,需要通过MapReduce功能来实现聚合以及批处理,它跟SQL里用来实现聚合的GROUP BY从句比较类似。下一节将描述关系数据库中SQL方式实现的聚合和相应的通过MongoDB提供的MapReduce实现的聚合。

为了讨论这个主题,我们考虑如下所示的Sales表,它以MongoDB中的反范式形式呈现。

Sales表

#

列名

数据类型

1

OrderId

INTEGER

2

OrderDate

STRING

3

Quantity

INTEGER

4

SalesAmt

DOUBLE

5

Profit

DOUBLE

6

CustomerName

STRING

7

City

STRING

8

State

STRING

9

ZipCode

STRING

10

Region

STRING

11

ProductId

INTEGER

12

ProductCategory

STRING

13

ProductSubCategory

STRING

14

ProductName

STRING

15

ShipDate

STRING

基于SQL和MapReduce的实现

我们提供了一个查询的样例集,这些查询使用聚合函数、过滤条件和分组从句,及其等效的MapReduce实现,即MongoDB实现SQL中GROUP BY的等效方式。在MongoDB存储的文档上执行聚合操作非常有用,这种方式的一个*是聚合函数(比如,SUM、AVG、MIN、MAX)需要通过mapper和reducer函数来定制化实现。

MongoDB没有原生态的用户自定义函数(UDFs)支持。但是它允许使用db.system.js.save命令来创建并保存JavaScript函数,JavaScript函数可以在MapReduce中复用。下表是一些常用的聚合函数的实现。稍后,我们会讨论这些函数在MapReduce任务中的使用。

聚合函数

Javascript 函数

SUM

db.system.js.save( { _id : "Sum" ,

value : function(key,values)

{

var total = 0;

for(var i = 0; i < values.length; i++)

total += values[i];

return total;

}});

AVERAGE

db.system.js.save( { _id : "Avg" ,

value : function(key,values)

{

var total = Sum(key,values);

var mean = total/values.length;

return mean;

}});

MAX

db.system.js.save( { _id : "Max" ,

value : function(key,values)

{

var maxValue=values[0];

for(var i=1;i

MIN

db.system.js.save( { _id : "Min" ,

value : function(key,values)

{

var minValue=values[0];

for(var i=1;i

VARIANCE

db.system.js.save( { _id : "Variance" ,

value : function(key,values)

{

var squared_Diff = 0;

var mean = Avg(key,values);

for(var i = 0; i < values.length; i++)

{

var deviation = values[i] - mean;

squared_Diff += deviation * deviation;

}

var variance = squared_Diff/(values.length);

return variance;

}});

STD DEVIATION

db.system.js.save( { _id : "Standard_Deviation"

, value : function(key,values)

{

var variance = Variance(key,values);

return Math.sqrt(variance);

}});

SQL和MapReduce脚本在四种不同的用例场景中实现聚合函数的代码片段如下表所示。

1.各地区的平均订单量

下面的查询是用来获取不同地区的平均订单量。

SQL Query

MapReduce Functions

SELECT

db.sales.runCommand(

{

mapreduce : "sales" ,

City,

State,

Region,

map:function()

{ // emit function handles the group by

emit( {

// Key

city:this.City,

state:this.State,

region:this.Region},

// Values

this.Quantity);

},

AVG(Quantity)

reduce:function(key,values)

{

var result = Avg(key, values);

return result;

}

FROM sales

GROUP BY City, State, Region

// Group By is handled by the emit(keys, values)

line in the map() function above

out : { inline : 1 } });

2.产品的分类销售总额

下面的查询是用来获取产品的分类销售额,根据产品类别的层级分组。在下面例子中,不同的产品类别作为个体维度,它们也可以被称为更复杂的基于层次的维度。

SQL 查询

MapReduce 函数

SELECT

db.sales.runCommand(

{

mapreduce : "sales" ,

ProductCategory, ProductSubCategory, ProductName,

map:function()

{

emit(

// Key

{key0:this.ProductCategory,

key1:this.ProductSubCategory,

key2:this.ProductName},

// Values

this.SalesAmt);

},

SUM(SalesAmt)

reduce:function(key,values)

{

var result = Sum(key, values);

return result;

}

FROM sales

GROUP BY ProductCategory, ProductSubCategory, ProductName

// Group By is handled by the emit(keys, values)

line in the map() function above

out : { inline : 1 } });

3. 一种产品的最大利润

下面的查询是用来获取一个给定产品基于过滤条件的最大利润。

SQL查询

MapReduce 函数

SELECT

db.sales.runCommand(

{

mapreduce : "sales" ,

ProductId, ProductName,

map:function()

{

if(this.ProductId==1)

emit( {

key0:this.ProductId,

key1:this.ProductName},

this.Profit);

},

MAX(SalesAmt)

reduce:function(key,values)

{

var maxValue=Max(key,values);

return maxValue;

}

FROM sales

WHERE ProductId=’1’

// WHERE condition implementation is provided in

map() function

GROUP BY ProductId, ProductName

// Group By is handled by the emit(keys, values)

line in the map() function above

out : { inline : 1 } });

4. 总量、总销售额、平均利润

这个场景的需求是计算订单的总数、总销售额和平均利润,订单ID在1到10之间,发货时间在2011年的1月1日到12月31日之间。下面的查询是用来执行多个聚合,比如,在指定年份以及指定的不同区域和产品类别范围里订单的总数、总销售额和平均利润。

SQL 查询

MapReduce 函数

SELECT

db.sales.runCommand(

{ mapreduce : "sales" ,

Region,

ProductCategory,

ProductId,

map:function()

{

emit( {

// Keys

region:this.Region,

productCategory:this.ProductCategory,

productid:this.ProductId},

// Values

{quantSum:this.Quantity,

salesSum:this.SalesAmt,

avgProfit:this.Profit} );

}

Sum(Quantity),

Sum(Sales),

Avg(Profit)

reduce:function(key,values)

{

var result=

{quantSum:0,salesSum:0,avgProfit:0};

var count = 0;

values.forEach(function(value)

{

// Calculation of Sum(Quantity)

result.quantSum += values[i].quantSum;

// Calculation of Sum(Sales)

result.salesSum += values[i].salesSum;

result.avgProfit += values[i].avgProfit;

count++;

}

// Calculation of Avg(Profit)

result.avgProfit = result.avgProfit / count;

return result;

},

FROM Sales

WHERE

Orderid between 1 and 10 AND

Shipdate BETWEEN ‘01/01/2011’ and

‘12/31/2011’

query : {

"OrderId" : { "$gt" : 1 },

"OrderId" : { "$lt" : 10 },

"ShipDate" : { "$gt" : "01/01/2011" },

"ShipDate" : { "$lt" : "31/12/2011" },

},

GROUP BY

Region, ProductCategory, ProductId

// Group By is handled by the emit(keys, values)

line in the map() function above

LIMIT 3;

limit : 3,

out : { inline : 1 } });

既然我们已经看了在不同业务场景下的聚合函数的代码示例,接下来我们准备来测试这些函数。

测试聚合函数

MongoDB的MapReduce功能通过数据库命令来调用。Map和Reduce函数在前面章节里已经使用JavaScript实现。下面是执行MapReduce函数的语法。

db.runCommand(

{ mapreduce : <collection>,

map : <mapfunction>,

reduce : <reducefunction>

[, query : <query filter object>]

[, sort : <sorts the input objects using this key. Useful for

optimization, like sorting by the emit key for fewer reduces>]

[, limit : <number of objects to return from collection>]

[, out : <see output options below>]

[, keeptemp: <true|false>]

[, finalize : <finalizefunction>]

[, scope : <object where fields go into javascript global scope >]

[, jsMode : true]

[, verbose : true]

}

)

Where the Output Options include:

{ replace : "collectionName" }

{ merge : "collectionName"

{ reduce : "collectionName" }

{ inline : 1}

如何删除MongoDB数据库中的文件

一、Insert操作

Insert操作是MongoDB插入数据的基本方法,对目标集合使用Insert操作,会将该文档添加到MongoDB并自动生成相应的ID键。文档结构采用类似JSON的BSON格式。常见的插入操作主要有单条插入和批量插入两种形式。插入时只是简单地将文档存入数据库中,不进行额外的验证,也不会执行代码,所以不存在注入式攻击的可能。

1、单条插入

2、批量插入

MongoDB对批量插入的支持是通过传递多个文档组成的数组到数据库来实现的。由于它插入数据是通过发送TCP请求的,这样只需发送单个TCP请求,且数据库无需处理大量的消息头,减少插入时间。这种方式的批量插入一次只能将多个文档插入到一个集合中,对于插入到多个集合可以循环调用Insert操作。

二、Remove操作

remove函数可以用来删除数据,能接受一个文档作为可选参数,只有符合条件的文档才会被删除。删除数据是永久性的,不能撤销,也不能恢复,需要谨慎。删除文档需要清空整个集合,不如直接删除集合快。

三、Update操作

update函数用于修改数据库中的数据,接收两个参数,一个是查询文档,用来查找要更新的文档,另一个是修改器文档,用来描述对找到的文档做哪些修改。更新操作是原子性的,如果多个更新同时发生,则所有的更新都会执行,但最后的更新是最终赢家。

1、整体更新(文档替换)

2、局部更新(修改器)

部分更新是通过原子的更新修改器实现的,使用修改器时除了”_id“的值不能改变,其他任何值都能改变。文档替换是可以改变所有值的。

$inc修改器:将指定属性的值增加特定的步长,如果键不存在则创建。

$set修改器:用来指定一个键的值,如果不存在则创建。

$push:数组修改器,如果指定的键存在,则向已有的数组末尾加入一个元素,键不存在则会创建一个新的数组。

3、upsert操作

upsert操作具有saveOrUpdate的功能,如果没有文档符合更新条件,则以更新条件和更新文档为基础创建一个新的文档。如果有符合更新条件的文档,则正常更新。创建新文档时会以条件文档作为基础,将修改器作用其之上。upsert操作是原子性的,高效的。

四、瞬间完成

上面的插入,删除和更新操作都是瞬间完成的,不需要等待数据库响应。这样的实现可以获取高性能,速度非常快,只会受客户端发送速度和网络速度的制约。但由于不会获取服务器状态,所以不能保证操作顺利完成。这对于付费系统,安全性较高的系统是不可行的,此时对这些操作需要使用的安全版本。安全版本会在操作执行后立即运行getLastError命令,来检查是否执行成功。如果失败一般会抛出可捕获的异常,然后可以在代码中处理。

MongoDB数据库中 db.foo.find() 中 "db"指的什么?

楼主是想搞清楚db是系统对象还是某一个数据库的名字(比如教学管理数据库)

db

foo

find()

都是数据库管理系统里面的东东

use test

switched to db test

先use打开一个数据库,然后把系统变量db的地址指向test,这样子db.foo.find()中的db就是test数据库了呀,把switched to db test看成C指针赋值一样吧

mongodb中如何实现类似于sql中的groupby?

mongodb中实现sql中德group by可以采用聚合函数aggregate

参考代码:

/**

* select avg(pop) avgCitypop from zipsController group by state

*/

exports.avgGroupByStateCityDemo2Async = function (opts) {

var results = {error_code: -1, error_msg: "error"};

var pipeline =[

{

$group: {

_id: "$state",

avgCitypop: {$avg: "$pop"}

}

}

];

return opts.dbs.csdb.collection("zipsController").aggregateAsync(pipeline)

  • 本文相关:
  • mongodb 数据库的命名、设计规范详解
  • 28个mongodb经典面试题详解
  • mongodb常用数据库命令大全
  • 修复 mac brew 安装 mongodb 报 error: no available formula with the name ‘mongodb’ 问题详解
  • mongodb启动报错 28663 cannot start server
  • node.js操作mongodb数据库实例分析
  • mongodb数据库安装配置、基本操作实例详解
  • windows10安装mongodb4.0详细步骤及启动配置教程
  • nodejs对mongodb数据库的增加修删该查实例代码
  • mongodb基本命令实例小结
  • win10 64位安装mongodb数据库的详细教程
  • linux下安装mongodb教程
  • python操作redis和mongodb的方法
  • dotnet core链接mongodb代码实例
  • zabbix3.4监控mongodb数据库状态的方法
  • windows安装压缩版mongodb的教程
  • 在laravel中使用mongodb的方法示例
  • 关于mongodb谨防索引seek的效率问题详析
  • mongodb使用小结 一些常用操作分享
  • mongodb 学习笔记(一)-mongodb配置
  • mongodb数据库误删后的恢复方法(两种)
  • mongodb自动删除过期数据的方法(ttl索引)
  • mongodb启动命令参数中文说明
  • mongodb的基本安装与管理命令脚本总结
  • mongodb整库备份与还原以及单个collection备份、恢复方法
  • mongodb修改数据的2种方法
  • 在linux服务器中配置mongodb环境的步骤
  • mongodb官方的golang驱动基础使用教程分享
  • mongodb replace函数 只能替换一条吗
  • 如何实现mongodb中的sum汇总操作?
  • 如何删除MongoDB数据库中的文件
  • MongoDB数据库中 db.foo.find() 中 "db"指的什么?
  • mongodb中如何实现类似于sql中的groupby?
  • mongodb如何查询某个字段的最大值?
  • 为什么我用php查询mongodb数据库中的某个集合中的文档的条数,得到的结果和实际情况不一致?
  • js怎么把mongodb里面的数据以json形式输出
  • mongod可以代替sqlserver吗
  • mongodb千万级别的数据分析怎么做
  • 免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved