Skip to content

值得您信賴的旅遊品牌 | 團體旅遊、自由行的專家‎

機場接送

Menu
  • 首頁
  • 旅遊天地
  • 裝潢設計
  • 環保清潔
  • 發燒車訊
Menu

MongoDB 4.X CRUD基本操作

Posted on 2021-03-192021-03-19 by admin

本文總結了MongoDB 4.X在mongo shell客戶端涉及的對文檔一些基本的增刪改查操作,即CRUD操作。主要結合了自己平時使用MongoDB的操作命令,更詳細的命令可以參考官方文檔: https://docs.mongodb.com/manual/crud/ 。

創建(Create Operations)

創建(Create Operations)也叫插入操作,當集合不存在時,插入操作同時也會創建集合。MongoDB提供以下幾種插入文檔方法:

  • db.collection.insert():在指定集合中插入單個或多個文檔。
  • db.collection.insertOne():在指定集合中插入單個文檔(版本3.2新增)。
  • db.collection.insertMany():在指定集合中插入多個文檔(版本3.2新增)。

db.collection.insert()

在平時的使用當中,db.collection.insert()是我用得最多的文檔插入方式,具體的語法格式如下:

db.collection.insert(
   <document or array of documents>,
   {
     writeConcern: <document>,
     ordered: <boolean>
   }
)

參數說明:

  • document:指定一個或多個文檔;
  • writeConcern:文檔寫入確認級別(可選),關於讀寫策略確認級別,以後再進行討論;
  • ordered:指定文檔是否按順序插入(可選),默認為true;
    • 當指定為true時,插入多個文檔時將文檔排序保存在一個數組中進行插入,如果其中有一個文檔插入失敗,則會導致數組中餘下的文檔不進行插入操作;
    • 當指定為false時,插入多個文檔時將文檔不進行排序保存在一個數組中進行插入,如果其中有一個文檔插入失敗,則不影響數組中餘下的文檔進行插入操作。

如果插入的文檔當中沒有指定_id字段,則MongoDB會自動為文檔生成具有唯一ObjectId值的字段_id。

使用示例:

// 沒有指定_id字段的插入單個文檔
db.products.insert( { item: "card", qty: 15 } );

// 指定_id字段的插入單個文檔
db.products.insert( { _id: 10, item: "box", qty: 20 } );

// 插入多個文檔,不進行排序,多個文檔包含在數組[]中
db.products.insert(
   [
     { _id: 11, item: "pencil", qty: 50, type: "no.2" },
     { item: "pen", qty: 20 },
     { item: "eraser", qty: 25 }
   ]
);

// 插入多個文檔,並進行排序
db.products.insert(
   [
     { _id: 20, item: "lamp", qty: 50, type: "desk" },
     { _id: 21, item: "lamp", qty: 20, type: "floor" },
     { _id: 22, item: "bulk", qty: 100 }
   ],
   { ordered: false }
);

db.collection.insertOne()

語法格式如下:

db.collection.insertOne(
   <document>,
   {
      writeConcern: <document>
   }
)

參數說明:

參考db.collection.insert()的參數說明。

使用示例:

// 單行插入文檔,關於_id字段指定與否也與db.collection.insert()一致
db.products.insertOne( { item: "card", qty: 15 } );

db.collection.insertMany()

語法格式如下:

db.collection.insertMany(
   [ <document 1> , <document 2>, ... ],
   {
      writeConcern: <document>,
      ordered: <boolean>
   }
)

參數說明:

參考db.collection.insert()的參數說明。

使用示例:

參考db.collection.insert()的參數說明。

關於返回確認信息

db.collection.insert()在插入文檔成功之後返回的信息相對較為簡潔:

db.products.insert( { item: "card", qty: 15 } );
WriteResult({ "nInserted" : 1, "writeConcernError" : [ ] })

db.collection.insertOne()和db.collection.insertMany()返回的信息較為詳細:

db.products.insertOne( { item: "card", qty: 15 } );
{
    "acknowledged": true,
    "insertedId": ObjectId("5eccbd214139000074003be8")
}

db.products.insertMany( [
      { _id: 10, item: "large box", qty: 20 },
      { _id: 11, item: "small box", qty: 55 },
      { _id: 12, item: "medium box", qty: 30 }
   ] );
{
    "acknowledged": true,
    "insertedIds": [
        10,
        11,
        12
    ]
}

查詢(Read Operations)

查詢(Read Operations)讀操作,是對集合中已存在的文檔進行查詢,即對應關係型數據庫當中的select操作,比如MySQL,MongoDB提供以下幾種主要查詢文檔方法:

  • db.collection.find():查詢指定集合中滿足條件的一個或多個文檔和視圖;
  • db.collection.findOne():查詢指定集合中滿足條件的第一個文檔,並以格式化方式展現,通過pretty()方法。

來自官方文檔的測試數據:

db.inventory.insertMany([
   { item: "journal", qty: 25, size: { h: 14, w: 21, uom: "cm" }, status: "A" },
   { item: "notebook", qty: 50, size: { h: 8.5, w: 11, uom: "in" }, status: "A" },
   { item: "paper", qty: 100, size: { h: 8.5, w: 11, uom: "in" }, status: "D" },
   { item: "planner", qty: 75, size: { h: 22.85, w: 30, uom: "cm" }, status: "D" },
   { item: "postcard", qty: 45, size: { h: 10, w: 15.25, uom: "cm" }, status: "A" }
]);

db.collection.find()

db.collection.find()可以說是使用頻率最高的方法了,可以用來查詢數據庫集合當中的文檔。

語法格式如下:

db.collection.find(<query>, <projection>)
  • query:查詢表達式;
  • projection:指定查詢結果集中需要显示的字段。
    • Col_name:1|true 代表显示該字段;
    • Col_name:0 | false 代表不显示該字段。

_id字段是默認显示的,如果不想显示,則顯式指定{"_id" : 0}。

查詢所有文檔:

db.inventory.find()

或

db.inventory.find({})

db.collection.findOne()

db.collection.findOne()方法显示符合條件查詢的第一條文檔,接受的參數與db.collection.find()方法一致。

條件查詢操作符

通常對文檔的查詢,是需要帶條件的,而很少使用到不帶條件的全文檔檢索,以下總結了幾種常使用的查詢操作符:

比較操作符

比較操作符涉及的操作如下錶所示:

名稱 說明
$eq 與指定值相等
$gt 大於指定的值
$gte 大於或等於指定的值
$in 指定的值在數組中
$lt 小於指定的值
$lte 小於或等於指定的值
$ne 所有不等於指定的值
$nin 指定的值不在數組中

使用示例:

// $eq:等值查詢 SQL: SELECT * FROM inventory WHERE status = "D";
db.inventory.find( { status: "D" } )

// $ne 同$eq

// $gt:範圍查詢(以大於為例) SQL: SELECT * FROM inventory WHERE qty > 30;
db.inventory.find( { qty: { $gt: 30 } } )

// $gte、$lt、$lte 同$gt

// $in:或查詢,可使用or代替 SQL: SELECT * FROM inventory WHERE status in ("A", "D")
db.inventory.find( { status: { $in: [ "A", "D" ] } } )

// $nin 同$in

邏輯操作符

邏輯操作符涉及的操作如下錶所示:

名稱 說明
$and 指定查詢同時滿足多個條件查詢子句
$not 指定查詢不滿足條件查詢子句
$nor 指定查詢無法滿足多個條件查詢子句
$or 指定查詢滿足其中某個條件查詢子句

使用示例:

// $and: 邏輯與查詢 SQL: SELECT * FROM inventory WHERE status = "A" AND qty < 30;
db.inventory.find( { $and: [ { status: { $eq: "A" },  qty: { $lt: 30 } } ] } )

// $not: 不符合查詢 SQL: SELECT * FROM inventory WHERE status <> "A";
db.inventory.find( { status: { $not: { $eq: "A" } } } )

/*
$nor: 無法同時滿足多個條件查詢,字段不存在時也符合 SQL: SELECT * FROM inventory WHERE status <> "A" AND qty > 30; 
符合以下條件之一都會出現在結果集中:
1.文檔包含status和qty字段並且符合條件;
2.文檔包含status字段並且符合條件,不包含qty字段;
3.文檔不包含status字段,包含qty字段並且符合條件;
4.文檔不包含status字段和qty字段。
*/
db.inventory.find( { $nor: [ { status: { $eq: "A" } },  { qty: { $lt: 30 } } ] } )

// $or: 邏輯或查詢 SQL: SELECT * FROM inventory WHERE status = "A" OR qty < 30;
db.inventory.find( { $or: [ { status: "A" }, { qty: { $lt: 30 } } ] } )

元素操作符

元素操作符主要涉及的操作如下錶所示:

名稱 說明
$exists 指定查詢文檔是否有對應的字段
$type 指定查詢文檔的某個字段是否是對應類型

使用示例:

// $exists: 是否存在指定字段查詢
db.inventory.find( { price: { $exists: true } } )

// $type: 字段是否是指定類型查詢
db.inventory.find( { "qty": { $type: "double" } } )

評估操作符

評估操作符主要涉及的操作如下錶所示,更多操作符可以參考官方文檔:https://docs.mongodb.com/manual/reference/operator/query-evaluation/。

名稱 說明
$expr 為同一個文檔中的字段指定表達式並且符合條件的查詢,比如比較同一文檔當中兩個字段的值
$mod 為字段值取模並且符合條件的查詢

為了更好的使用這兩個主要的操作符,額外創建個文檔:

db.monthlyBudget.insertMany([
    { "_id" : 1, "category" : "food", "budget": 400, "spent": 450 },
    { "_id" : 2, "category" : "drinks", "budget": 100, "spent": 150 },
    { "_id" : 3, "category" : "clothes", "budget": 100, "spent": 50 },
    { "_id" : 4, "category" : "misc", "budget": 500, "spent": 300 },
    { "_id" : 5, "category" : "travel", "budget": 200, "spent": 650 }
]);

使用示例:

// $expr: 允許使用聚合表達式,這裏以$gt為例,更多表達式參考 https://docs.mongodb.com/manual/meta/aggregation-quick-reference/#aggregation-expressions
db.monthlyBudget.find( { $expr: { $gt: [ "$spent" , "$budget" ] } } )

// $mod: 對字段所在值進行取模運算,显示符合條件的查詢,如qty字段值對4取模,並且餘數為0
db.inventory.find( { qty: { $mod: [ 4, 0 ] } } )

更新(Update Operations)

更新(Update Operations)是對已存在的文檔進行修改操作,MongoDB提供以下幾種主要更新文檔方法:

  • db.collection.update():更新或替換集合中符合條件的一個或多個文檔;
  • db.collection.updateOne():只更新集合中符合條件的第一個文檔,即使有多個文檔(版本3.2新增);
  • db.collection.updateMany():更新集合中所有符合條件的文檔(版本3.2新增)。

db.collection.update()

根據update指定的表達式可以修改文檔中符合條件的字段或代替整個文檔。具體的語法格式如下:

db.collection.update(
   <query>,   //查詢表達式
   <update>,  //更新表達式
   {
     upsert: <boolean>,
     multi: <boolean>,
     writeConcern: <document>,
     collation: <document>,
     arrayFilters: [ <filterdocument1>, ... ],
     hint:  <document|string>                   // 版本4.2新增
   }
)

參數說明:

  • query:更新文檔的查詢表達式;如果指定了參數upsert: true並且集合中沒有符合查詢條件的文檔,查詢條件中有關於字段_id指定了.分隔符的,並不會插入新的文檔;

  • update:主要包含三種格式

    • 1.更新文檔:只包含更新操作符表達式;
    • 2.替換文檔:只包含<field1>: <value1>對;
    • 3.聚合管道:版本4.2新增,詳細參考官方文檔。
  • upsert:當query查詢條件沒符合更新的文檔,就新創建文檔(可選),默認值為false;

  • multi:是否更新多個符合條件的文檔(可選),默認值為false,只更新符合條件的第一個文檔;

  • writeConcern:參考db.collection.insert()相同參數說明;

  • collation:指定校對規則(可選,版本3.4新增);

  • arrayFilters:文檔數組更新過濾操作符(可選,版本3.6新增);

    詳細參考:https://docs.mongodb.com/manual/reference/method/db.collection.update/#specify-arrayfilters-for-array-update-operations

  • hint:採用文檔或字符串的形式指定適用於查詢表達式的索引,如果索引不存在則報錯(可選,版本4.2新增)。

使用示例:

使用示例將通過使用兩種場景進行,一是沒有使用參數選項upsert,二是使用參數選項upsert。

  • 不使用選項upsert
// 測試數據
db.books.remove({});

db.books.insertMany([
  {
    "_id" : 1,
    "item" : "TBD",
    "stock" : 0,
    "info" : { "publisher" : "1111", "pages" : 430 },
    "tags" : [ "technology", "computer" ],
    "ratings" : [ { "by" : "ijk", "rating" : 4 }, { "by" : "lmn", "rating" : 5 } ],
    "reorder" : false
   },
   {
    "_id" : 2,
    "item" : "XYZ123",
    "stock" : 15,
    "info" : { "publisher" : "5555", "pages" : 150 },
    "tags" : [ ],
    "ratings" : [ { "by" : "xyz", "rating" : 5 } ],
    "reorder" : false
   }
]);


/* 使用選項參數 upsert: true
1、如果查詢表達式找到匹配的文檔,則執行更新操作;
2、如果查詢表達式沒有找到匹配的文檔,則執行插入操作;
*/
db.books.update(
   { item: "ZZZ135" },   // 查詢表達式
   {                     // 更新或替換文檔
     item: "ZZZ135",
     stock: 5,
     tags: [ "database" ]
   },
   { upsert: true }
);

// 1.使用更新操作表達式
/* $set操作符
1、查詢表達式指定需要更新的文檔 _id;
2、$inc操作符: stock的字段值+5;
3、$set操作符: 替換item字段值,替換嵌入文檔info的publisher字段值,替換tags字段值,替換數組ratings的第二個元素值
*/
db.books.update(
   { _id: 1 },
   {
     $inc: { stock: 5 },
     $set: {
       item: "ABC123",
       "info.publisher": "2222",
       tags: [ "software" ],
       "ratings.1": { by: "xyz", rating: 3 }
     }
   }
);
更新之後的文檔:
{

  "_id" : 1,
  "item" : "ABC123",
  "stock" : 5,
  "info" : { "publisher" : "2222", "pages" : 430 },
  "tags" : [ "software" ],
  "ratings" : [ { "by" : "ijk", "rating" : 4 }, { "by" : "xyz", "rating" : 3 } ],
  "reorder" : false
}

// 2.為已存在的數組添加元素
// $push操作符: 為指定文檔數組ratings添加一個元素
db.books.update(
   { _id: 2 },
   {
     $push: { ratings: { "by" : "jkl", "rating" : 2 } }
   }
);
更新之後的文檔:
{
  "_id" : 2,
  "item" : "XYZ123",
  "stock" : 15,
  "info" : {
   "publisher" : "5555",
   "pages" : 150
  },
  "tags" : [ ],
  "ratings" : [
   { "by" : "xyz", "rating" : 5 },

   { "by" : "jkl", "rating" : 2 }

  ],
  "reorder" : false
 }

// 3.文檔移除字段
// $unset操作符: 移除文檔的指定字段,為_id:1文檔移除tags字段
db.books.update( { _id: 1 }, { $unset: { tags: 1 } } );
更新后的文檔:
{
  "_id" : 1,
  "item" : "TBD",
  "stock" : 0,
  "info" : {
   "publisher" : "1111",
   "pages" : 430
  },
  "ratings" : [ { "by" : "ijk", "rating" : 4 }, { "by" : "lmn", "rating" : 5 } ],
  "reorder" : false
 }

// 4.替換整個文檔
// 替換_id:2的文檔
db.books.update(
   { _id: 2 },
   {
     item: "XYZ123",
     stock: 10,
     info: { publisher: "2255", pages: 150 },
     tags: [ "baking", "cooking" ]
   }
);
更新后的文檔:
{
   "_id" : 2,
   "item" : "XYZ123",
   "stock" : 10,
   "info" : { "publisher" : "2255", "pages" : 150 },
   "tags" : [ "baking", "cooking" ]
}

// 5.更新多個文檔
db.books.update(
   { stock: { $lte: 10 } },
   { $set: { reorder: true } },
   { multi: true }
);
更新后的全部文檔:
[
  {
    "_id" : 1,
    "item" : "ABC123",
    "stock" : 5,
    "info" : {
     "publisher" : "2222",
     "pages" : 430
    },
    "ratings" : [ { "by" : "ijk", "rating" : 4 }, { "by" : "xyz", "rating" : 3 } ],

    "reorder" : true

   }
   {
     "_id" : 2,
     "item" : "XYZ123",
     "stock" : 10,
     "info" : { "publisher" : "2255", "pages" : 150 },
     "tags" : [ "baking", "cooking" ],

     "reorder" : true

   }
]
  • 使用upserts選項
/* 使用選項參數 upsert: true
1、如果查詢表達式找到匹配的文檔,則執行更新操作;
2、如果查詢表達式沒有找到匹配的文檔,則執行插入操作;
*/

// 1.插入未符合更新條件的文檔
db.books.update(
   { item: "ZZZ135" },   
   {                     
     item: "ZZZ135",
     stock: 5,
     tags: [ "database" ]
   },

   { upsert: true }      

);
因為集合併未滿足條件的文檔,則插入的文檔為:
{
  "_id" : ObjectId("5da78973835b2f1c75347a83"),
  "item" : "ZZZ135",
  "stock" : 5,
  "tags" : [ "database" ]
}

// 2.插入未符合更新條件並且基於更新操作符的文檔
// 如果沒有符合更新查詢條件,並且使用的是更新操作符,則會基於當前的查詢條件和更新操作符字段插入新的文檔
db.books.update(
   { item: "BLP921" },   
   {                     
      $set: { reorder: false },
      $setOnInsert: { stock: 10 }
   },
   { upsert: true }      
);
新插入的文檔為:
{
  "_id" : ObjectId("5da79019835b2f1c75348a0a"),
  "item" : "BLP921",
  "reorder" : false,
  "stock" : 10
}

// 3.插入未符合更新條件並且基於聚合管道的文檔
// 關於聚合管道請參考官方文檔:https://docs.mongodb.com/manual/reference/method/db.collection.update/#update-with-aggregation-pipeline

// 4.插入未符合更新條件並且同時聯合多文檔操作符的文檔
如果不符合查詢條件,則只會插入單個文檔
db.books.update(
  { "info.publisher": "Self-Published" },   
  {                                         
    $set: { reorder: false, tags: [ "literature", "hardcover" ], stock: 25 }
  },
  { upsert: true, multi: true }             
);
新插入的文檔:
{
  "_id" : ObjectId("5db337934f670d584b6ca8e0"),
  "info" : { "publisher" : "Self-Published" },
  "reorder" : false,
  "stock" : 25,
  "tags" : [ "literature", "hardcover" ]
}

db.collection.updateOne()

根據update指定的參數可以修改文檔中符合條件的字段或代替整個文檔,與db.collection.update()不同的是每次只更新單個文檔。

語法格式如下:

db.collection.updateOne(
   <filter>,
   <update>,
   {
     upsert: <boolean>,
     writeConcern: <document>,
     collation: <document>,
     arrayFilters: [ <filterdocument1>, ... ],
     hint:  <document|string>        
   }
)

參數說明:

參考db.collection.update()的參數說明。

使用示例:

// 參考db.collection.update()

db.collection.updateMany()

根據update指定的參數可以修改文檔中符合條件的字段或代替整個文檔,與db.collection.updateOne()不同的是更新所有符合條件的文檔。

語法格式如下:

db.collection.updateMany(
   <filter>,
   <update>,
   {
     upsert: <boolean>,
     writeConcern: <document>,
     collation: <document>,
     arrayFilters: [ <filterdocument1>, ... ],
     hint:  <document|string>        
   }
)

參數說明:

參考db.collection.update()的參數說明。

使用示例:

// 參考db.collection.update()

刪除(Delete Operations)

刪除是指對集合當中已存在的文檔進行清除操作,MongoDB提供以下幾種主要刪除文檔方法:

  • db.collection.deleteOne():只刪除集合中符合條件的一個文檔;
  • db.collection.deleteMany():刪除集合中所有符合條件的文檔;
  • db.collection.remove():刪除集合中符合條件的一個或多個文檔。

db.collection.deleteOne()

根據filter選項條件刪除集合中的單個文檔,具體語法格式如下:

db.collection.deleteOne(
   <filter>,
   {
      writeConcern: <document>,
      collation: <document>
   }
)

參數說明:

  • filter:指定基於查詢表達式的過濾條件,關於查詢表達式可以查看db.collecion.find()中的<query>;
  • writeConcern:參考db.collection.insert()相同參數說明;
  • collation:指定校對規則(可選,版本3.4新增);

使用示例:

// 刪除指定條件的單個文檔
db.orders.deleteOne( { "_id" : 1 } );
{ "acknowledged" : true, "deletedCount" : 1 }

db.collection.deleteMany()

根據filter選項條件刪除集合中的單個文檔,具體語法格式如下:

db.collection.deleteMany(
   <filter>,
   {
      writeConcern: <document>,
      collation: <document>
   }
)

參數說明:

參考db.collection.deleteOne()的參數說明。

使用示例:

// 刪除指定條件的多個文檔
db.orders.deleteMany( {"cust_id" : "Cam Elot"} );
{ "acknowledged" : true, "deletedCount" : 2 }

注意: 如果是對固定集合進行刪除文檔操作則會報錯,固定集合的清除操作使用方法db.collection.drop()。

總結

  1. 本文簡單梳理了在Mongo Shell下基本的CRUD操作,主要適用於DBA的運維管理,如果是研發同學,根據不同的編程語言使用不同客戶端驅動進行操作,詳細同樣可以參考官方文檔;
  2. 針對CRUD各個方面還有其他一些額外的方法,比如查詢修改文檔方法db.collection.findAndModify(),這裏只是總結每個文檔操作中一些最基礎的方法,對於額外高級的方法這裏不再贅述;
  3. 掌握了這些基本的CRUD操作,就可以對MongoDB文檔進行操作了,但還是需要控制好權限,畢竟數據安全不是小事,做變更之前做好數據的備份,以防萬一。

參考

https://docs.mongodb.com/manual/crud/

https://docs.mongodb.com/manual/reference/operator/query-evaluation/

https://docs.mongodb.com/manual/reference/method/db.collection.update/#specify-arrayfilters-for-array-update-operations

https://docs.mongodb.com/manual/reference/method/db.collection.update/#update-with-aggregation-pipeline

〖本人水平有限,文中如有錯誤還請留言批評指正!〗

本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※網頁設計公司推薦不同的風格,搶佔消費者視覺第一線

※廣告預算用在刀口上,台北網頁設計公司幫您達到更多曝光效益

※自行創業缺乏曝光? 網頁設計幫您第一時間規劃公司的形象門面

※南投搬家公司費用需注意的眉眉角角,別等搬了再說!

※教你寫出一流的銷售文案?

※回頭車貨運收費標準

※別再煩惱如何寫文案,掌握八大原則!

好站推薦

  • 健康醫療 減重知識專區
  • 婚紗世界 婚紗攝影寫真網
  • 成人話題 未滿18請勿進入
  • 流行時尚 時下流行愛美情報
  • 理財資訊 當舖借貸信用卡各式理財方法
  • 生活情報 各行各業情報資訊
  • 科技資訊 工業電子3C產品
  • 網路資訊 新奇趣味爆笑內容
  • 美食分享 全台各式名產 伴手禮
  • 裝潢設計 買屋賣屋裝修一羅框
  • 視覺設計 T恤、團體服、制服、polo衫

近期文章

  • 疑似小米手環 6 規格與新功能現身!加入血氧飽和偵測、GPS、更多運動模式_網頁設計公司
  • Microsoft 365 還是 Google Workspace?一文看懂企業生產力工具選哪套_如何寫文案
  • Sony Mobile 全新 Xperia Compact 小尺寸手機回歸?爆料大神釋出高清晰渲染圖_網頁設計公司
  • 微軟最新的廣告,直白地跟你說 Surface Pro 7 就是比 MacBook Pro 好_網頁設計
  • MagSafe 會干擾心律調節器?蘋果支援頁面有正式解答了_貨運

標籤

USB CONNECTOR  南投搬家公司費用 古典家具推薦 台中室內設計 台中室內設計師 台中搬家 台中搬家公司 台中電動車 台北網頁設計 台東伴手禮 台東名產 地板施工 大圖輸出 如何寫文案 婚禮錄影 宜蘭民宿 家具工廠推薦 家具訂製工廠推薦 家具訂製推薦 實木地板 床墊 復刻家具推薦 新竹婚宴會館 木地板 木質地板 柚木地板 桃園機場接送 桃園自助婚紗 沙發修理 沙發換皮 海島型木地板 潭子電動車 牛軋糖 租車 網站設計 網頁設計 網頁設計公司 貨運 超耐磨木地板 銷售文案 隱形鐵窗 電動車 馬賽克拼貼 馬賽克磁磚 馬賽克磚

彙整

  • 2021 年 4 月
  • 2021 年 3 月
  • 2021 年 2 月
  • 2021 年 1 月
  • 2020 年 12 月
  • 2020 年 11 月
  • 2020 年 10 月
  • 2020 年 9 月
  • 2020 年 8 月
  • 2020 年 7 月
  • 2020 年 6 月
  • 2020 年 5 月
  • 2020 年 4 月
  • 2020 年 3 月
  • 2020 年 2 月
  • 2020 年 1 月
  • 2019 年 12 月
  • 2019 年 11 月
  • 2019 年 10 月
  • 2019 年 9 月
  • 2019 年 8 月
  • 2019 年 7 月
  • 2019 年 6 月
  • 2019 年 5 月
  • 2019 年 4 月
  • 2019 年 3 月
  • 2019 年 2 月
  • 2019 年 1 月
  • 2018 年 12 月
©2021 值得您信賴的旅遊品牌 | 團體旅遊、自由行的專家‎ | Built using WordPress and Responsive Blogily theme by Superb