มีแบบสอบถามสำหรับการคำนวณจำนวนค่าที่แตกต่างกันในเขตข้อมูลใน DB
ฉันมีเขตข้อมูลสำหรับประเทศและมีค่าประเทศ 8 ประเภท (สเปนอังกฤษฝรั่งเศส ฯลฯ ... )
หากมีคนเพิ่มเอกสารในประเทศใหม่ฉันต้องการให้แบบสอบถามส่งคืน 9
มีวิธีที่ง่ายกว่าแล้วจัดกลุ่มและนับหรือไม่?
มีแบบสอบถามสำหรับการคำนวณจำนวนค่าที่แตกต่างกันในเขตข้อมูลใน DB
ฉันมีเขตข้อมูลสำหรับประเทศและมีค่าประเทศ 8 ประเภท (สเปนอังกฤษฝรั่งเศส ฯลฯ ... )
หากมีคนเพิ่มเอกสารในประเทศใหม่ฉันต้องการให้แบบสอบถามส่งคืน 9
มีวิธีที่ง่ายกว่าแล้วจัดกลุ่มและนับหรือไม่?
คำตอบ:
MongoDB มีdistinctคำสั่งที่ส่งคืนอาร์เรย์ของค่าที่แตกต่างกันสำหรับฟิลด์ คุณสามารถตรวจสอบความยาวของอาร์เรย์เพื่อนับจำนวน
มีตัวdb.collection.distinct()ช่วยเชลล์เช่นกัน:
> db.countries.distinct('country');
[ "Spain", "England", "France", "Australia" ]
> db.countries.distinct('country').length
4
นี่คือตัวอย่างของการใช้ aggregation API เพื่อทำให้กรณีซับซ้อนขึ้นเรากำลังจัดกลุ่มตามคำที่ไม่คำนึงถึงตัวพิมพ์เล็กและใหญ่จากคุณสมบัติอาร์เรย์ของเอกสาร
db.articles.aggregate([
{
$match: {
keywords: { $not: {$size: 0} }
}
},
{ $unwind: "$keywords" },
{
$group: {
_id: {$toLower: '$keywords'},
count: { $sum: 1 }
}
},
{
$match: {
count: { $gte: 2 }
}
},
{ $sort : { count : -1} },
{ $limit : 100 }
]);
ที่ให้ผลลัพธ์เช่น
{ "_id" : "inflammation", "count" : 765 }
{ "_id" : "obesity", "count" : 641 }
{ "_id" : "epidemiology", "count" : 617 }
{ "_id" : "cancer", "count" : 604 }
{ "_id" : "breast cancer", "count" : 596 }
{ "_id" : "apoptosis", "count" : 570 }
{ "_id" : "children", "count" : 487 }
{ "_id" : "depression", "count" : 474 }
{ "_id" : "hiv", "count" : 468 }
{ "_id" : "prognosis", "count" : 428 }
unwindเป็นสิ่งที่จำเป็นเนื่องจากรหัสกำลังจัดกลุ่มค่าแต่ละค่าของฟิลด์อาร์เรย์ซึ่งตรงกับวิธีการdistinctทำงาน
unwindเป็นสิ่งที่จำเป็นเมื่อทำงานกับอาร์เรย์
ด้วย MongoDb 3.4.4 และใหม่กว่าคุณสามารถใช้ประโยชน์จากการใช้$arrayToObjectตัวดำเนินการและ$replaceRootไปป์ไลน์เพื่อรับจำนวน
ตัวอย่างเช่นสมมติว่าคุณมีกลุ่มผู้ใช้ที่มีบทบาทที่แตกต่างกันและคุณต้องการคำนวณจำนวนบทบาทที่แตกต่างกัน คุณจะต้องเรียกใช้ไปป์ไลน์รวมต่อไปนี้:
db.users.aggregate([
{ "$group": {
"_id": { "$toLower": "$role" },
"count": { "$sum": 1 }
} },
{ "$group": {
"_id": null,
"counts": {
"$push": { "k": "$_id", "v": "$count" }
}
} },
{ "$replaceRoot": {
"newRoot": { "$arrayToObject": "$counts" }
} }
])
ตัวอย่างผลลัพธ์
{
"user" : 67,
"superuser" : 5,
"admin" : 4,
"moderator" : 12
}
.distinct()ฉันสงสัยว่าการดำเนินการนี้เมื่อเทียบกับ
คุณสามารถใช้ประโยชน์จากMongo เชลล์ส่วนขยาย มันเป็นการนำเข้า. js เดียวที่คุณสามารถต่อท้ายของคุณ$HOME/.mongorc.jsหรือทางโปรแกรมได้หากคุณกำลังเข้ารหัสใน Node.js / io.js ด้วย
ตัวอย่าง
สำหรับแต่ละค่าที่แตกต่างกันของเขตข้อมูลจะนับจำนวนที่เกิดขึ้นในเอกสารที่เลือกกรองตามแบบสอบถาม
>
db.users.distinctAndCount('name', {name: /^a/i})
{
"Abagail": 1,
"Abbey": 3,
"Abbie": 1,
...
}
พารามิเตอร์ฟิลด์อาจเป็นอาร์เรย์ของฟิลด์
>
db.users.distinctAndCount(['name','job'], {name: /^a/i})
{
"Austin,Educator" : 1,
"Aurelia,Educator" : 1,
"Augustine,Carpenter" : 1,
...
}
require("./script.js")ฉันคิดว่า
.mongorc.jsไฟล์ลงใน dir ที่บ้านของคุณ เสร็จแล้ว
หากต้องการค้นหาความแตกต่างในfield_1คอลเลกชัน แต่เราต้องการWHEREเงื่อนไขบางอย่างเกินกว่าที่เราจะทำได้ดังต่อไปนี้:
db.your_collection_name.distinct('field_1', {WHERE condition here and it should return a document})
ดังนั้นค้นหาหมายเลขที่แตกต่างnamesจากคอลเล็กชันที่อายุ> 25 จะเป็นดังนี้:
db.your_collection_name.distinct('names', {'age': {"$gt": 25}})
หวังว่าจะช่วยได้!
ฉันใช้แบบสอบถามนี้:
var collection = "countries"; var field = "country";
db[collection].distinct(field).forEach(function(value){print(field + ", " + value + ": " + db.hosts.count({[field]: value}))})
เอาท์พุต:
countries, England: 3536
countries, France: 238
countries, Australia: 1044
countries, Spain: 16
การค้นหานี้จะทำให้ค่าทั้งหมดแตกต่างกันก่อนจากนั้นจึงนับจำนวนครั้งที่เกิดขึ้นสำหรับแต่ละค่า