เมื่อชื่อฟิลด์ (Key) มีจุด (.) อยู่ภายใน ไม่สามารถค้นหาได้โดยตรง ต้องใช้ Aggregation Pipeline ร่วมกับ $objectToArray, $filter และ $indexOfBytes เพื่อแปลงและกรองคีย์ที่มีจุด
ตัวอย่างข้อมูลทดสอบ
> db.demo364.insertOne({
"details" : {
"details1.otherdetails.Name" : {"FirstName":"Chris"}
}
});
> db.demo364.insertOne({
"details" : {
"details1.otherdetails.Name" : {"FirstName":"David"}
}
});
แสดงข้อมูลทั้งหมด
> db.demo364.find();
{
"_id" : ObjectId("5e57d485d0ada61456dc936d"),
"details" : { "details1.otherdetails.Name" : { "FirstName" : "Chris" } }
}
{
"_id" : ObjectId("5e57d486d0ada61456dc936e"),
"details" : { "details1.otherdetails.Name" : { "FirstName" : "David" } }
}
คำสั่ง Aggregation สำหรับค้นหาคีย์ที่มีจุด
> db.demo364.aggregate([
{
$addFields: {
result: {
$filter: {
input: { $objectToArray: "$details" },
cond: {
$ne: [
{ $indexOfBytes: [ "$$this.k", "." ] },
-1
]
}
}
}
}
},
{
$match: {
$expr: {
$ne: [ { $size: "$result" }, 0 ]
}
}
},
{
$project: { result: 0 }
}
])
ผลลัพธ์
{
"_id" : ObjectId("5e57d485d0ada61456dc936d"),
"details" : { "details1.otherdetails.Name" : { "FirstName" : "Chris" } }
}
{
"_id" : ObjectId("5e57d486d0ada61456dc936e"),
"details" : { "details1.otherdetails.Name" : { "FirstName" : "David" } }
}
คำอธิบาย:
$objectToArrayแปลงออบเจ็กต์เป็นอาร์เรย์ของ key-value pairs$filterกรองเฉพาะรายการที่คีย์ (k) มีจุด (.) โดยใช้$indexOfBytes$matchกรองเอกสารที่มีผลลัพธ์จากการ filter ไม่ว่างเปล่า$projectซ่อนฟิลด์ช่วยเหลือ result