[英]Validate embedded document in mongodb
我想在MongoDB中驗證我的文檔。 如所描述的在這里 ,可以在過程中指定的驗證查詢createCollection
命令。
我的應用程序是一個簡單的待辦事項列表,因此收集list
包含許多這樣的文檔:
{
"name": "the list name",
"color: "red",
"items": [
{
"title": "item1",
"isDone": false,
"text": "the item description"
}
]
}
如何確定所有文檔都具有這種形狀?
編輯:我正在使用MongoDB 3.4
你不能
沒有避免新財產的方法。 如果需要此要求,則應考慮遷移SQL解決方案。
否則,您的文檔將至少包含那些成員,並且這些成員將被驗證。
我假設所有字段都是必填字段,所以沒有顏色的列表和沒有標題的項目都不能添加。
我認為顏色也是一個枚舉。
{
validator: {
name: { $type: 'string', $exists: true },
color: { $in: ['red', 'green', 'blue'], $exists: true },
items: { $exists: true },
$or: [
{ items: { $size: 0 } },
{
$and: [
{ 'items.0': { $exists: true } },
{
items: {
$not: {
$elemMatch: {
$not: { $type: 'object' }
}
}
}
},
{
items: {
$not: {
$elemMatch: {
$or: [
{ title: { $not: { $type: 'string' } } },
{ title: { $not: { $exists: true } } },
{ isDone: { $not: { $type: 'bool' } } },
{ isDone: { $not: { $exists: true } } },
{ text: { $not: { $type: 'string' } } },
{ text: { $not: { $exists: true } } }
]
}
}
}
}
]
}
]
}
}
說明
該解決方案基於二階邏輯 。 實際上,斷言“所有元素都必須匹配A”等於“沒有元素應該匹配!A”,或者,如果您有許多查詢,“所有元素必須匹配A和B”變為“沒有元素應該匹配!A或B”。 !B”,在哪里!
表示以下謂詞的否定。
詳細說明
前兩個查詢項目斷言所有文檔都具有name
和color
,第三個查詢items
屬性始終存在。 注意:在第三個查詢屬性中,沒有$type
檢查,因為mongodb 以奇怪的方式處理array
類型。
需要下面的$or
操作,因為item
屬性可以為空或可以填充一些數據。
$or
第一個子句檢查數組是否為空。 如果數組不為空,則應進行三項檢查:
因此,第一個$and
運算符元素檢查是否存在至少一個元素。 第二個檢查所有數組元素都是對象。 第三個斷言所有對象都具有指定的形狀。
在mongodb中,有一個運算符用於檢查所有數組元素是否與查詢匹配。 因此,應使用二階邏輯將檢查移交。
實際上, $and
的最后兩個子句檢查沒有元素與所描述的查詢匹配。 每個子查詢都是所需查詢的否定項。
例
失敗
{ name: 'foo' }
{ color: 'red' }
{ color: 'unknown color' }
{ name: 'foo', color: 'red' }
{ name: 'foo', color: 'red', item: 3 }
{ name: 'foo', color: 'red', item: [ 3 ] }
{ name: 'foo', color: 'red', item: [ { } ] }
{ name: 'foo', color: 'red', item: [ { title: 'ww' } ] }
{ name: 'foo', color: 'red', item: [ { title: 'ww', isDone: false } ] }
{ name: 'foo', color: 'red', item: [ { title: 44, isDone: false, text: 'the text' } ] }
通過
{ name: 'foo', color: 'red', items: [ ] },
{ name: 'foo', color: 'red', items: [ ] },
{ name: 'foo', color: 'red', items: [ { title: 'the title', isDone: false, text: 'the text' }, { title: 'the title1', isDone: true, text: 'the text' } ] }
該解決方案在MongoDB 3.2上仍然有效
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.