บทนี้นำเสนอคำอธิบายอย่างละเอียดเกี่ยวกับการวิเคราะห์ทางสถิติของ MongoDB ซึ่งทำได้หลักโดยใช้ Aggregation Pipeline มันคล้ายกับคำสั่ง "group by" ใน SQL เราสามารถทำการวิเคราะห์ทางสถิติใน MongoDB shell โดยใช้ฟังก์ชัน db.collection.aggregate()
ขั้นตอนพื้นฐานของการวิเคราะห์
- ใช้
$match
เพื่อกรองข้อมูลเป้าหมาย - ใช้
$group
เพื่อจัดกลุ่มและคำนวณข้อมูล - ใช้
$sort
เพื่อเรียงลำดับผลลัพธ์ (ตัวเลือก)
ข้อมูลทดสอบ
ข้อมูลในคอลเลคชัน orders
มีดังนี้
{ _id: 1, cust_id: "abc1", ord_date: ISODate("2012-11-02T17:04:11.102Z"), status: "A", amount: 50 }
{ _id: 2, cust_id: "xyz1", ord_date: ISODate("2013-10-01T17:04:11.102Z"), status: "A", amount: 100 }
{ _id: 3, cust_id: "xyz1", ord_date: ISODate("2013-10-12T17:04:11.102Z"), status: "D", amount: 25 }
{ _id: 4, cust_id: "xyz1", ord_date: ISODate("2013-10-11T17:04:11.102Z"), status: "D", amount: 125 }
{ _id: 5, cust_id: "abc1", ord_date: ISODate("2013-11-12T17:04:11.102Z"), status: "A", amount: 25 }
ฟังก์ชัน aggregate
db.collection.aggregate(pipeline)
คำอธิบาย:
-
pipeline
รับพารามิเตอร์เป็นอาร์เรย์ ที่แต่ละองค์แทนสเตจการประมวลผล
ตัวอย่าง
db.orders.aggregate([
{ $match: { status: "A" } }, // สเตจแรก
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } }, // สเตจที่สอง
{ $sort: { total: -1 } } // สเตจที่สาม (ตัวเลือก)
])
SQL เทียบเท่า
select sum(amount) as total from orders
where status="A"
group by cust_id
order by total desc
สเตจ $match
รูปแบบ:
{ $match: { <query> } }
คำอธิบาย:
-
<query>
เงื่อนไขคิวรี MongoDB
ใช้เพื่อตั้งเงื่อนไขคิวรี ถ้า $match
ถูกละเลย นั้นหมายความว่าการคิวรีข้อมูลทั้งหมด
เกร้ด: หากคุณไม่เคยใช้กับการคิวรีเชิงฐานข้อมูล MongoDB กรุณาอ้างถึงบทที่ผ่านมา
สเตจ $group
คล้ายกับคำสั่ง group by
ใน SQL ใช้เพื่อจัดกลุ่มข้อมูลและทำการคำนวณทางสถิติต่าง ๆ บนข้อมูลที่จัดกลุ่ม
การใช้งานพื้นฐานของ $group
รูปแบบ:
{
$group:
{
_id: <expression>, // เงื่อนไขการจัดกลุ่ม เช่น: จัดกลุ่มโดยใด
<field1>: { <accumulator1> : <expression1> }, // การดำเนินการคำนวณ คุณสามารถเพิ่มการดำเนินการคำนวณ N ตัว
...
}
}
คำอธิบาย:
-
- ชื่อของตัวชี้วัดสถิติแบบกำหนดเอง สามารถเป็น N ในรวม -
- ฟังก์ชันการคำนวณ คล้ายกับการบวก หาค่าเฉลี่ยและฟังก์ชันการคำนวณอื่น ๆ ของ SQL ต่างกันที่ฟังก์ชันการคำนวณของ MongoDB จะถูกตั้งชื่อด้วยเครื่องหมาย $ เช่น: $sum, $avg -
- พารามิเตอร์ของฟังก์ชันการคำนวณ โดยธรรมชาติคือค่าของฟิลด์ที่ต้องการนับ การอ้างถึงฟิลด์ของเอกสารโดยใช้รูปแบบ "$ชื่อฟิลด์"
ตัวอย่าง:
db.orders.aggregate([
{
$group: {
_id: "$cust_id",
total: { $sum: "$amount" }, // เพิ่มตัวชี้วัดแรกที่คำนวณได้ total โดยใช้ตัวดำเนินการผลรวม $sum
amount_avg: {$avg: "$amount"} // เพิ่มตัวชี้วัดที่คำนวณได้สอง ค่าเฉลี่ย amount_avg โดยใช้ตัวดำเนินการคำนวณเฉลี่ย $avg
}
}
])
ผลลัพธ์:
{ "_id" : "abc1", "total" : 75, "amount_avg" : 37.5 }
{ "_id" : "xyz1", "total" : 250, "amount_avg" : 83.33333333333333 }
SQL เทียบเท่า:
select
sum(amount) as total,
avg(amount) as amount_avg
from orders
group by cust_id
ฟังก์ชันการรวมกลุ่ม $group
ฟังก์ชันการรวมกลุ่มชนิดที่ใช้บ่อยสำหรับ $group มีดังนี้:
ตัวดำเนินการ | คำอธิบาย | ตัวอย่าง |
---|---|---|
$avg | คำนวณค่าเฉลี่ย | {$avg: "$amount"} |
$sum | ผลรวม | {$sum: "$amount"} |
$max | ค่าสูงสุด | {$max: "$amount"} |
$min | ค่าต่ำสุด | {$min: "$amount"} |
$first | คืนค่าข้อมูลหลังจากรวมกลุ่ม คือเนื้อหาของเอกสารแรก | {$first: "$amount"} |
$last | คืนค่าข้อมูลหลังจากรวมกลุ่ม คือเนื้อหาของเอกสารสุดท้าย | {$last: "$amount"} |
$push | คืนค่าข้อมูลหลังจากรวมกลุ่ม | { $push: { ord_date: "$ord_date", amount: "$amount" } |
$addToSet | คืนค่าข้อมูลหลังจากรวมกลุ่ม ต่างจาก $push โดยที่มันจะเอาค่าซ้ำออก | { $addToSet: "$amount" } |
ตัวอย่างการใช้งาน $push
db.orders.aggregate(
[
{
$group:
{
_id: "$cust_id",
all: { $push: { ord_date: "$ord_date", amount: "$amount" } } // ค่าของฟิลด์ ord_date และ amount
}
}
]
)
ผลลัพธ์
{ "_id" : "abc1", "all" : [ { "ord_date" : "2021-04-18 00:00:00", "amount" : 50 }, { "ord_date" : "2021-04-21 00:00:00", "amount" : 25 } ] }
{ "_id" : "xyz1", "all" : [ { "ord_date" : "2021-04-18 00:00:00", "amount" : 100 }, { "ord_date" : "2021-04-20 00:00:00", "amount" : 25 }, { "ord_date" : "2021-04-21 00:00:00", "amount" : 125 } ] }
ตัวอย่างการใช้งาน $addToSet
db.orders.aggregate(
[
{
$group:
{
_id: "$cust_id",
all_amount: { $addToSet: "$amount" } // คืนค่าทั้งหมดของค่า amount ที่แตกต่างกัน
}
}
]
)
ผลลัพธ์
{ "_id" : "abc1", "all_amount" : [ 25, 50 ] }
{ "_id" : "xyz1", "all_amount" : [ 100, 25, 125 ] }
$sort:
ขั้นตอน $sort มักถูกวางไว้ที่ท้ายเพื่อเรียงลำดับข้อมูลที่รวมกัน
รูปแบบ:
{ $sort: { <field1>: <sort order>, <field2>: <sort order> ... } }
อธิบาย:
-
, - ชื่อของฟิลด์ที่จะเรียงลำดับ รองรับหลายฟิลด์ -
- ทิศทางของการเรียงลำดับ -1 สำหรับการเรียงจากมากไปหาน้อย 1 สำหรับการเรียงจากน้อยไปหามาก
ตัวอย่าง:
db.orders.aggregate([
{ $match: { status: "A" } },
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } },
{ $sort: { total: -1 } }
])
การแบ่งหน้าข้อมูลที่รวมกัน
เราสามารถทำการแบ่งหน้าโดยใช้ตัวดำเนินการ $limit และ $skip
ตัวอย่าง:
db.orders.aggregate([
{ $match: { status: "A" } },
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } },
{ $sort: { total: -1 } },
{ $limit: 5 }, // จำกัดจำนวนรายการที่คืนค่า คล้ายกับขนาดหน้าในการแบ่งหน้า
{ $skip: 1 } // ข้ามจำนวนรายการบางรายการ คล้ายกับออฟเซ็ตใน SQL
])