ใช้ Map-Reduce หา Index ของค่าในอาร์เรย์
MongoDB ไม่มีฟังก์ชัน Built-in สำหรับหา Index ของค่าในอาร์เรย์โดยตรง แต่สามารถใช้ mapReduce ร่วมกับ JavaScript Array.indexOf() ได้
ตัวอย่างข้อมูล
> db.retrievePositionDemo.find().pretty();
{ "_id" : ObjectId("5cd569ec7924bb85b3f4893f"), "Subjects" : [ "MySQL", "MongoDB", "Java" ] }
Map-Reduce: หา Index ของ "MongoDB"
> db.retrievePositionDemo.mapReduce(
function() {
emit(this._id, { "IndexValue": this.Subjects.indexOf("MongoDB") });
},
function() {},
{
"out": { "inline": 1 },
"query": { "Subjects": "MongoDB" }
}
);
ผลลัพธ์
{ "results" : [
{ "_id" : ObjectId("5cd569ec7924bb85b3f4893f"), "value" : { "IndexValue" : 1 } }
], "timeMillis" : 662, "counts" : { "input" : 1, "emit" : 1, "reduce" : 0, "output" : 1 }, "ok" : 1 }
ค่า IndexValue: 1 หมายถึง "MongoDB" อยู่ตำแหน่งที่ 1 (0-based index)
ทดสอบหา "Java" (ตำแหน่งที่ 2)
> db.retrievePositionDemo.mapReduce(
function() {
emit(this._id, { "IndexValue": this.Subjects.indexOf("Java") });
},
function() {},
{
"out": { "inline": 1 },
"query": { "Subjects": "MongoDB" }
}
);
ผลลัพธ์: IndexValue: 2
วิธีทันสมัยกว่า (MongoDB 4.4+): ใช้ $indexOfArray ใน Aggregation
db.retrievePositionDemo.aggregate([
{ $match: { Subjects: "MongoDB" } },
{ $project: {
_id: 1,
index: { $indexOfArray: ["$Subjects", "MongoDB"] }
}}
]);
ผลลัพธ์ Aggregation
{ "_id" : ObjectId("5cd569ec7924bb85b3f4893f"), "index" : 1 }
สรุป
- Map-Reduce: วิธีเก่า ใช้ได้ทุกเวอร์ชัน แต่ช้าและซับซ้อน
$indexOfArray(Aggregation): เร็วกว่า อ่านง่ายกว่า รองรับ Index$indexOfArrayคืนค่า -1 ถ้าไม่เจอค่าที่ค้นหา