阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

MongoDB的查询操作

196次阅读
没有评论

共计 13017 个字符,预计需要花费 33 分钟才能阅读完成。

1. 前言

在这篇文章中,我们将学习如何查询 mongoDB 中的数据。当我们把数据存储在 mongoDB 以后,我们需要把数据查询出来。毕竟 CRUD 操作中,查询操作在我们系统中是我们应用比较频繁的操作。我们需要应对不同的业务需求,构造合适的查询条件去查询我们想要的数据。我们需要去学习 mongoDB 给我们提供了哪些查询相关的语法和功能。在这里,我们使用 mongodb 自带的 mongo shell(mongo shell 是一个 Javascript 环境的 mongodb 客户端,支持 js 语法)来学习。

2. 准备

在开始之前,我们需要准备一下实验用的数据:

MongoDB 的查询操作

// 启动 mongo shell 客户端
$ mongo

// 在这里我们使用 test 数据库,如果没有这个数据库,会自动创建
> use test

// 在 users collection 中插入 6 条用户数据
> db.users.insertMany(
  [
     {_id: 1,
       name: "sue",
       age: 19,
       type: 1,
       status: "P",
       favorites: {artist: "Picasso", food: "pizza" },
       finished: [17, 3 ],
       badges: ["blue", "black" ],
       points: [{ points: 85, bonus: 20 },
          {points: 85, bonus: 10 }
       ]
     },
     {_id: 2,
       name: "bob",
       age: 42,
       type: 1,
       status: "A",
       favorites: {artist: "Miro", food: "meringue" },
       finished: [11, 25 ],
       badges: ["green" ],
       points: [{ points: 85, bonus: 20 },
          {points: 64, bonus: 12 }
       ]
     },
     {_id: 3,
       name: "ahn",
       age: 22,
       type: 2,
       status: "A",
       favorites: {artist: "Cassatt", food: "cake" },
       finished: [6 ],
       badges: ["blue", "red" ],
       points: [{ points: 81, bonus: 8 },
          {points: 55, bonus: 20 }
       ]
     },
     {_id: 4,
       name: "xi",
       age: 34,
       type: 2,
       status: "D",
       favorites: {artist: "Chagall", food: "chocolate" },
       finished: [5, 11 ],
       badges: ["red", "black" ],
       points: [{ points: 53, bonus: 15 },
          {points: 51, bonus: 15 }
       ]
     },
     {_id: 5,
       name: "xyz",
       age: 23,
       type: 2,
       status: "D",
       favorites: {artist: "Noguchi", food: "nougat" },
       finished: [14, 6 ],
       badges: ["orange" ],
       points: [{ points: 71, bonus: 20 }
       ]
     },
     {_id: 6,
       name: "abc",
       age: 43,
       type: 1,
       status: "A",
       favorites: {food: "pizza", artist: "Picasso" },
       finished: [18, 12 ],
       badges: ["black", "blue" ],
       points: [{ points: 78, bonus: 8 },
          {points: 57, bonus: 7 }
       ]
     }
  ]
)

3. 基本查询

MongoDB 提供了 db.collection.find() 方法来执行查询操作。find 方法接受两个参数:一个查询条件,一个是投影的字段。这两个参数都不是必须的,如果省略了查询条件,则默认列出 collection 中的所有文档。

db.users.find()

// 这个和上面的语句是等价的
db.users.find({})

3.1 等值查询

通过 find()方法来执行等值查询的时候,可以通过 {<field>:<value>} 的方式来指定查询条件,这个条件表示在 collection 中查询满足 field 的值为 value 的所有文档。假设我们需要查找所有 status 是 ’A’ 的用户,我们可以这么查询:

db.users.find({status: 'A'})

查询结果

{"_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "favorites" : { "artist" : "Cassatt", "food" : "cake"}, "finished" : [6], "badges" : ["blue", "red"], "points" : [{ "points" : 81, "bonus" : 8}, {"points" : 55, "bonus" : 20 } ] }
{"_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : {"food" : "pizza", "artist" : "Picasso"}, "finished" : [18, 12], "badges" : ["black", "blue"], "points" : [{ "points" : 78, "bonus" : 8}, {"points" : 57, "bonus" : 7} ] }

3.2 操作符查询

mongodb 支持使用操作符来构造查询条件,比如比较操作符,如 $gt,$lt 等。使用操作符的查询条件通过 {<field>: {<operator>:<value>}} 来表示。假设我们要查询 age 超过 22 的用户,可以这么做:

db.users.find({age: {$gt: 22}})

查询结果

{"_id" : 2, "name" : "bob", "age" : 42, "type" : 1, "status" : "A", "favorites" : { "artist" : "Miro", "food" : "meringue"}, "finished" : [11, 25], "badges" : ["green"], "points" : [{ "points" : 85, "bonus" : 20}, {"points" : 64, "bonus" : 12 } ] }
{"_id" : 4, "name" : "xi", "age" : 34, "type" : 2, "status" : "D", "favorites" : {"artist" : "Chagall", "food" : "chocolate"}, "finished" : [5, 11], "badges" : ["red", "black"], "points" : [{ "points" : 53, "bonus" : 15}, {"points" : 51, "bonus" : 15 } ] }
{"_id" : 5, "name" : "xyz", "age" : 23, "type" : 2, "status" : "D", "favorites" : {"artist" : "Noguchi", "food" : "nougat"}, "finished" : [14, 6], "badges" : ["orange"], "points" : [{ "points" : 71, "bonus" : 20 } ] }
{"_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : {"food" : "pizza", "artist" : "Picasso"}, "finished" : [18, 12], "badges" : ["black", "blue"], "points" : [{ "points" : 78, "bonus" : 8}, {"points" : 57, "bonus" : 7} ] }

3.3 and 关系

mongodb 支持的 and 关系查询很简单,当一个查询条件中包含多个 <field:value> 对的时候,这些条件之间的关系就是 and 关系。所以 and 关系的查询可以这样表示{<field1>:<value1>, <field2>:<value2>, …,<fieldN>:<valueN>}。假设我们要查询满足条件:status 是 ’D’,并且 age 大于 23 的用户,我们可以这么查询:

db.users.find({status: 'D', age: {$gt: 23}})

查询结果

"_id" : 4, "name" : "xi", "age" : 34, "type" : 2, "status" : "D", "favorites" : {"artist" : "Chagall", "food" : "chocolate"}, "finished" : [5, 11], "badges" : ["red", "black"], "points" : [{ "points" : 53, "bonus" : 15}, {"points" : 51, "bonus" : 15} ] }

3.4 or 关系

mongodb 通过操作符 ”$or” 来支持 or 关系的查询。or 关系的查询条件可以这么构造:{$or: [{<field1>:<value1>}, {<field2>:<value2>},…, {<fieldN>:<valueN>}]}。比如我们想查询 status 是 ’A’ 或者 age 大于 23 的用户,我们可以这么做:

db.users.find({$or: [{status: 'A'}, {age: {$gt: 23}}]})

查询条件

{"_id" : 2, "name" : "bob", "age" : 42, "type" : 1, "status" : "A", "favorites" : { "artist" : "Miro", "food" : "meringue"}, "finished" : [11, 25], "badges" : ["green"], "points" : [{ "points" : 85, "bonus" : 20}, {"points" : 64, "bonus" : 12 } ] }
{"_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "favorites" : {"artist" : "Cassatt", "food" : "cake"}, "finished" : [6], "badges" : ["blue", "red"], "points" : [{ "points" : 81, "bonus" : 8}, {"points" : 55, "bonus" : 20 } ] }
{"_id" : 4, "name" : "xi", "age" : 34, "type" : 2, "status" : "D", "favorites" : {"artist" : "Chagall", "food" : "chocolate"}, "finished" : [5, 11], "badges" : ["red", "black"], "points" : [{ "points" : 53, "bonus" : 15}, {"points" : 51, "bonus" : 15 } ] }
{"_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : {"food" : "pizza", "artist" : "Picasso"}, "finished" : [18, 12], "badges" : ["black", "blue"], "points" : [{ "points" : 78, "bonus" : 8}, {"points" : 57, "bonus" : 7} ] }

4. 嵌套文档查询

如果在文档中的一个字段上的值也是一个文档,当我们需要查询这个文档中的子文档中的值得时候,就涉及到嵌套文档的查询。MongoDB 支持对嵌套文档的查询。

4.1 匹配整个子文档

匹配整个子文档可以认为也是一种等值查询,只不过这次的值是一个子文档。所以查询条件就是这样的{<field>:<sub document>}。假设我们要查询 favorites 这个字段上,artist 为 ’Picasso’,food 为 ’pizza’ 的用户,我们可以这样做:

db.users.find({ favorites: { artist: "Picasso", food: "pizza"} } )

查询结果

{"_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza"}, "finished" : [17, 3], "badges" : ["blue", "black"], "points" : [{ "points" : 85, "bonus" : 20}, {"points" : 85, "bonus" : 10} ] }

4.2 匹配子文档中的字段

mongodb 支持匹配子文档中的字段,通过点 (.) 符号来表示子文档中的字段,比如我们在 favorites 字段对应的子文档中的 artist 字段上做查询操作,可以通过 favorites.artist 来表示这个子文档中的 artist 字段

db.users.find({ "favorites.artist": "Picasso"} )

查询结果

{"_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza"}, "finished" : [17, 3], "badges" : ["blue", "black"], "points" : [{ "points" : 85, "bonus" : 20}, {"points" : 85, "bonus" : 10 } ] }
{"_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : {"food" : "pizza", "artist" : "Picasso"}, "finished" : [18, 12], "badges" : ["black", "blue"], "points" : [{ "points" : 78, "bonus" : 8}, {"points" : 57, "bonus" : 7} ] }

5. 在数组上查询

如果文档中的字段的值是数组类型,mongodb 支持对数组类型的字段构造查询条件。

5.1 匹配整个数组

mongodb 对整个数组进行匹配的时候,和匹配整个嵌套文档的方式类似。只要在条件中给出整个数组就可以了,就像这样{<field>:<value>},只不过这里的 <value> 是需要匹配的整个数组。假设我们需要查找 badges 的值为 ”[‘blue’, ‘black’]” 的用户,我们可以这样做

db.users.find({ badges: [ "blue", "black"] } )

查询结果

{"_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza"}, "finished" : [17, 3], "badges" : ["blue", "black"], "points" : [{ "points" : 85, "bonus" : 20}, {"points" : 85, "bonus" : 10} ] }

5.2 查找数组中的一个元素

除了对数组类型的字段做完全匹配的查询,我们也可以把数组的元素作为查询条件,主要数组中包含了这个元素,那么都会被匹配到。比如我们需要查找 badges 的数组中包含了 ’black’ 元素的所有用户,我们可以这样做

db.users.find({ badges: "black"} )

查询结果

{"_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza"}, "finished" : [17, 3], "badges" : ["blue", "black"], "points" : [{ "points" : 85, "bonus" : 20}, {"points" : 85, "bonus" : 10 } ] }
{"_id" : 4, "name" : "xi", "age" : 34, "type" : 2, "status" : "D", "favorites" : {"artist" : "Chagall", "food" : "chocolate"}, "finished" : [5, 11], "badges" : ["red", "black"], "points" : [{ "points" : 53, "bonus" : 15}, {"points" : 51, "bonus" : 15 } ] }
{"_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : {"food" : "pizza", "artist" : "Picasso"}, "finished" : [18, 12], "badges" : ["black", "blue"], "points" : [{ "points" : 78, "bonus" : 8}, {"points" : 57, "bonus" : 7} ] }

可以看到,这三个用户的 badges 字段中的值中,都有‘black’元素在数组中。

5.3 匹配数组中指定下标的元素

mongodb 支持把数组中指定下标的元素作为查询条件来构造查询语句,通过类似于引用子文档的点号 (.) 方式来说引用指定下标的元素。比如 badges 字段中数组的第一个元素,可以表示成:badges.0,类似的,第 N 个就是badges.N。假设我们想查找满足 badges 数组中的第一个元素是 ’black’ 的用户,我们可以这样做:

db.users.find({ "badges.0": "black"} )

查询结果

{"_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : { "food" : "pizza", "artist" : "Picasso"}, "finished" : [18, 12], "badges" : ["black", "blue"], "points" : [{ "points" : 78, "bonus" : 8}, {"points" : 57, "bonus" : 7} ] }

查询结果看到,只有一个满足条件的用户。虽然别的用户的 badges 字段也有 ’black’ 字段,但是由于需要查找数组的第一个元素是 ’black’ 的用户,所以只有一个用户是满足条件的。

5.4 对数组元素指定多个查询条件

多个条件之间的 and 关系

mongodb 提供了一个 ”$elemMatch” 操作符,这个操作符的作用是对数组中的元素进行多条件匹配,只要数组中至少一个元素满足指定的条件,那么就表示匹配成功,也就是说,’$elemMatch’ 操作符指定的条件之间是 ” 与 ” 的关系。来看例子,假设我们要找到满足 finished 字段中的数组元素的值大于 15,小于 20,我们可以这样做:

db.users.find({ finished: { $elemMatch: { $gt: 15, $lt: 20} } } )

查询结果

{"_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza"}, "finished" : [17, 3], "badges" : ["blue", "black"], "points" : [{ "points" : 85, "bonus" : 20}, {"points" : 85, "bonus" : 10 } ] }
{"_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : {"food" : "pizza", "artist" : "Picasso"}, "finished" : [18, 12], "badges" : ["black", "blue"], "points" : [{ "points" : 78, "bonus" : 8}, {"points" : 57, "bonus" : 7} ] }

我们可以看到,“$elemMatch”操作符的用法,是用指定的多个条件来匹配数组中的每一个值,只要数组中至少有一个值满足我们指定的条件,就表示匹配成功。

多条件之间的 or 关系

mongodb 在数组匹配的时候,可以返回满足指定条件的结果的并集。通俗的讲,指定的条件之间是“或”的关系,即只要数组中的任何一个元素满足多个查询条件中的任何一个,那么就认为这个文档被匹配上了。比如,我们如果这样指定查询条件

db.users.find({ finished: { $gt: 15, $lt: 20} } )

我们先来看下查询的结果

{"_id" : 1, "name" : "sue", "age" : 19, "type" : 1, "status" : "P", "favorites" : { "artist" : "Picasso", "food" : "pizza"}, "finished" : [17, 3], "badges" : ["blue", "black"], "points" : [{ "points" : 85, "bonus" : 20}, {"points" : 85, "bonus" : 10 } ] }
{"_id" : 2, "name" : "bob", "age" : 42, "type" : 1, "status" : "A", "favorites" : {"artist" : "Miro", "food" : "meringue"}, "finished" : [11, 25], "badges" : ["green"], "points" : [{ "points" : 85, "bonus" : 20}, {"points" : 64, "bonus" : 12 } ] }
{"_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : {"food" : "pizza", "artist" : "Picasso"}, "finished" : [18, 12], "badges" : ["black", "blue"], "points" : [{ "points" : 78, "bonus" : 8}, {"points" : 57, "bonus" : 7} ] }

这个查询条件和上面的元素匹配的查询条件相比,查询的结果我们看到,中间的记录中,finished 的值是 [11, 25] 的也满足查询条件。这是因为 {finished: {$gt: 15, $lt: 20}} 这个条件,表示数组中的任何一个元素,只要满足大于 15 或者小于 20,都被认为是满足查询条件的,指定的条件之间是“或”的关系。而通过 ”$elemMatch” 操作符指定的查询条件,条件之间的关系是“与”的关系。所以不难理解,值为 [11, 25] 的那个记录之所以被匹配,是因为它满足 25 是大于条件中的 15 的,而 11 是小于条件中的 20 的,所以自然就满足条件了。

5.5 数组中包含子文档的查询

当数组中包含子文档的时候,也可以为这些子文档中的字段构造查询条件。

使用数组下标定位到具体的子文档

这种方式的查询条件,是同时利用数组的下标表示和文档中字段的点号 (.) 表示法来指定数组中子文档中的字段。讲的有点绕,我们来看具体的例子。

db.users.find({ 'points.0.points': { $lte: 55} } )

这条查询语句的意思,表示我们要查询 points 字段中,它包含的数组中下标为 0 的子文档中的 points 字段的值,满足条件{$lte: 55},也就是这个子文档中的 points 字段的值小于等于 55。查询结果如下:

{"_id" : 4, "name" : "xi", "age" : 34, "type" : 2, "status" : "D", "favorites" : { "artist" : "Chagall", "food" : "chocolate"}, "finished" : [5, 11], "badges" : ["red", "black"], "points" : [{ "points" : 53, "bonus" : 15}, {"points" : 51, "bonus" : 15} ] }

匹配任何一个满足条件的子文档

如果我们省略了数组的下标,那么查询条件就变成了这样

db.users.find({ 'points.points': { $lte: 55} } )

它表示查询 points 数组中任何一个子文档,只要子文档中的 points 字段的值满足条件 {$lte: 55} 就可以了。

查询结果:

{"_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "favorites" : { "artist" : "Cassatt", "food" : "cake"}, "finished" : [6], "badges" : ["blue", "red"], "points" : [{ "points" : 81, "bonus" : 8}, {"points" : 55, "bonus" : 20 } ] }
{"_id" : 4, "name" : "xi", "age" : 34, "type" : 2, "status" : "D", "favorites" : {"artist" : "Chagall", "food" : "chocolate"}, "finished" : [5, 11], "badges" : ["red", "black"], "points" : [{ "points" : 53, "bonus" : 15}, {"points" : 51, "bonus" : 15} ] }

可以看到,查询结果中包含了所有满足条件的记录。

多个条件之间的 and 关系

利用上面提到的数组的多条件“and”关系匹配的方法,也可以用来为数组中的子文档指定多个匹配条件。查询条件也是利用了 ”$elemMatch” 操作符:

db.users.find({ points: { $elemMatch: { points: { $lte: 70}, bonus: 20 } } } )

可以看到,我们在对 points 数组中的子文档指定多个匹配匹配条件的时候,和上面提到的对数组中元素指定多个匹配条件的方式类似。只不过,上面是对整数指定匹配条件,这里是换成了对子文档指定匹配条件,而且子文档中的字段可以直接引用,不用采用点 (.) 号的方式引用。

查询结果

{"_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "favorites" : { "artist" : "Cassatt", "food" : "cake"}, "finished" : [6], "badges" : ["blue", "red"], "points" : [{ "points" : 81, "bonus" : 8}, {"points" : 55, "bonus" : 20} ] }

多个条件之间的 or 关系

和对数组中元素指定多个 or 关系的查询条件一样,对数组中的子文档指定多个 or 关系的查询条件的语句,在形式上类似。来看具体的例子:

db.users.find({ "points.points": { $lte: 70}, "points.bonus": 20 } )

这里使用点 (.) 号来引用数组中的子文档的字段,其中两个条件之间是“或”的关系,语句的意思大体是这样的:查询满足 points 数组中,任何一个子文档的 points 字段的值不小于 70 或者任何一个子文档的 bonus 字段的值为 20 的记录。查询结果是这样的:

{"_id" : 2, "name" : "bob", "age" : 42, "type" : 1, "status" : "A", "favorites" : { "artist" : "Miro", "food" : "meringue"}, "finished" : [11, 25], "badges" : ["green"], "points" : [{ "points" : 85, "bonus" : 20}, {"points" : 64, "bonus" : 12 } ] }
{"_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "favorites" : {"artist" : "Cassatt", "food" : "cake"}, "finished" : [6], "badges" : ["blue", "red"], "points" : [{ "points" : 81, "bonus" : 8}, {"points" : 55, "bonus" : 20} ] }
 
如果我们对数组的下标做了指定,那么可以在上面的多个“or”条件之上,再加一个数组元素的位置限定。比如:
db.users.find({'points.0.points': {$gte: 70}, 'points.0.bonus': 8})

这里使用了上面提到的,在数组中指定下标的方式来指定数组中的某一个元素。

查询结果

{"_id" : 3, "name" : "ahn", "age" : 22, "type" : 2, "status" : "A", "favorites" : { "artist" : "Cassatt", "food" : "cake"}, "finished" : [6], "badges" : ["blue", "red"], "points" : [{ "points" : 81, "bonus" : 8}, {"points" : 55, "bonus" : 20 } ] }
{"_id" : 6, "name" : "abc", "age" : 43, "type" : 1, "status" : "A", "favorites" : {"food" : "pizza", "artist" : "Picasso"}, "finished" : [18, 12], "badges" : ["black", "blue"], "points" : [{ "points" : 78, "bonus" : 8}, {"points" : 57, "bonus" : 7} ] }

6. 总结

到这里,我们已经差不多讲完了 mongo 中有关查询语句的语法。从对简单值的查询,到对嵌套子文档的查询,再到数组的查询,最后到数组和子文档嵌套的复杂查询。以及如何对多个查询条件做“or”操作和“and”操作。希望这篇文章对各位有一些帮助吧。

讲了那么多,光看没用,还是要多动手实践,自己动手去敲一遍代码才会加深印象,如果能在项目中的业务场景中需要用到这些查询,那么就再好不过了。因为这样才会让这些知识更好地被吸收,不然就会掉入学了忘,忘了学的深渊之中。这其实也是写博客的好处,学了新的知识,即使不能马上用到工作中,通过一篇博客来巩固加深印象,虽然没在实际项目中使用产生的效果好,也是也是有一定的效果的。

更多 MongoDB 相关教程见以下内容

CentOS 编译安装 MongoDB 与 mongoDB 的 php 扩展 http://www.linuxidc.com/Linux/2012-02/53833.htm

CentOS 6 使用 yum 安装 MongoDB 及服务器端配置 http://www.linuxidc.com/Linux/2012-08/68196.htm

Ubuntu 13.04 下安装 MongoDB2.4.3 http://www.linuxidc.com/Linux/2013-05/84227.htm

MongoDB 入门必读(概念与实战并重) http://www.linuxidc.com/Linux/2013-07/87105.htm

Ubunu 14.04 下 MongoDB 的安装指南 http://www.linuxidc.com/Linux/2014-08/105364.htm

《MongoDB 权威指南》(MongoDB: The Definitive Guide)英文文字版[PDF] http://www.linuxidc.com/Linux/2012-07/66735.htm

Nagios 监控 MongoDB 分片集群服务实战 http://www.linuxidc.com/Linux/2014-10/107826.htm

基于 CentOS 6.5 操作系统搭建 MongoDB 服务 http://www.linuxidc.com/Linux/2014-11/108900.htm

MongoDB 的详细介绍:请点这里
MongoDB 的下载地址:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-10/136581.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-22发表,共计13017字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中