tl; dr
ใช่เป็นไปได้ที่จะมีเอกสารหลายฉบับที่มีการตั้งค่าฟิลด์เป็นnull
หรือไม่ได้กำหนดไว้ในขณะที่บังคับใช้ค่า "จริง" ที่ไม่ซ้ำกัน
ข้อกำหนด :
- MongoDB v3.2 +
- การรู้ประเภทมูลค่าคอนกรีตของคุณล่วงหน้า (เช่นเสมอ
string
หรือobject
เมื่อไม่ได้null
)
หากคุณไม่สนใจในรายละเอียดโปรดข้ามไปที่implementation
ส่วนนี้
รุ่นที่ยาวขึ้น
เพื่อเสริมคำตอบของ @ Nolan เริ่มต้นด้วย MongoDB v3.2 คุณสามารถใช้ดัชนีเฉพาะบางส่วนกับนิพจน์ตัวกรอง
นิพจน์ตัวกรองบางส่วนมีข้อ จำกัด สามารถรวมได้เฉพาะสิ่งต่อไปนี้:
- นิพจน์ความเท่าเทียมกัน (เช่นฟิลด์: ค่าหรือใช้ตัว
$eq
ดำเนินการ)
$exists: true
นิพจน์
$gt
, $gte
, $lt
, $lte
สำนวน
$type
นิพจน์
$and
ผู้ดำเนินการในระดับบนสุดเท่านั้น
ซึ่งหมายความว่า{"yourField"{$ne: null}}
ไม่สามารถใช้นิพจน์เล็กน้อยได้
แต่สมมติว่าข้อมูลของคุณมักจะใช้ชนิดเดียวกันคุณสามารถใช้การแสดงออก$type
{ field: { $type: <BSON type number> | <String alias> } }
MongoDB v3.6 เพิ่มการรองรับสำหรับการระบุประเภทที่เป็นไปได้หลายแบบซึ่งสามารถส่งผ่านเป็นอาร์เรย์:
{ field: { $type: [ <BSON type1> , <BSON type2>, ... ] } }
ซึ่งหมายความว่ามันจะช่วยให้ค่าเป็นใด ๆ null
ของจำนวนของหลายประเภทเมื่อไม่
ดังนั้นหากเราต้องการอนุญาตให้email
ฟิลด์ในตัวอย่างด้านล่างยอมรับstring
หรือกล่าวว่าbinary data
ค่า$type
นิพจน์ที่เหมาะสมจะเป็น:
{email: {$type: ["string", "binData"]}}
การนำไปใช้งาน
พังพอน
คุณสามารถระบุได้ในสคีมาพังพอน:
const UsersSchema = new Schema({
name: {type: String, trim: true, index: true, required: true},
email: {
type: String, trim: true, index: {
unique: true,
partialFilterExpression: {email: {$type: "string"}}
}
}
});
หรือเพิ่มลงในคอลเล็กชันโดยตรง (ซึ่งใช้ไดรเวอร์ node.js ดั้งเดิม):
User.collection.createIndex("email", {
unique: true,
partialFilterExpression: {
"email": {
$type: "string"
}
}
});
ไดรเวอร์ mongodb พื้นเมือง
โดยใช้ collection.createIndex
db.collection('users').createIndex({
"email": 1
}, {
unique: true,
partialFilterExpression: {
"email": {
$type: "string"
}
}
},
function (err, results) {
// ...
}
);
เปลือก mongodb
ใช้db.collection.createIndex
:
db.users.createIndex({
"email": 1
}, {
unique: true,
partialFilterExpression: {
"email": {$type: "string"}
}
})
วิธีนี้จะช่วยให้สามารถแทรกหลายระเบียนด้วยnull
อีเมลหรือไม่มีฟิลด์อีเมลเลย แต่จะไม่สามารถใช้สตริงอีเมลเดียวกันได้