我有一个相当大的json架构。有问题的部分是架构中较小的架构,称为" translations",它看起来像这样:
"translations": {
"bsonType": "object",
"patternProperties": {
"id": {
"bsonType": "string"
},
"^[a-z]{2}$": {
"anyOf": [
{
"bsonType": "object"
},
{
"bsonType": "array"
}
]
}
}
}
正则表达式定义的对象包含更多属性(例如,一个名为" text"的字段),并且数组是这些对象的数组,但我只留下了重要的部分了解结构。
我的问题是,当我根据这个模式验证我的文件时,它会失败每一个,但当我删除" bsonType":" object"从anyOf数组中的第一个对象开始,它可以正常工作。
我的所有文件都是这样的,翻译对象中至少有一个具有正则表达式作为键的对象属于" object"。所以我不明白为什么它们会失败。
我使用的是mongoDB 3.6.0。
以下是失败文件的示例:
"translations":{
"id":"12345",
"br":{
"text":"string1"
},
"en":{
"text":"string2"
},
"ja":[
{
"text":"string3"
},
{
"text":"string4"
}
],
"no":[
{
"text":"string6"
},
{
"text":"string7"
}
]
}
如果它不清楚 - 问题在于,当使用" bsonType":" object"定义模式时,这样的文件会失败。在anyOf数组的第一个对象中,当我取消它时工作。 " bsonType":"数组"在anyOf数组的第二个对象中工作正常。
答案 0 :(得分:1)
我认为你的id与正则表达式碰撞的问题试试这个:
let MongoClient = require('mongodb').MongoClient;
let collectionName = 'translations';
let scheme = {
$jsonSchema:{
"bsonType": "object",
"patternProperties": {
"^id$":{
"bsonType":"string"
},
"^(?!id)([a-z]{2})$": {
"anyOf": [
{
"bsonType": "object"
},
{
"bsonType": "array"
}
]
}
},
}
};
let goodJson ={
"id": "12345",
"br":{
"text":"string1"
},
"en":{
"text":"string2"
},
"ja":[
{
"text":"string3"
},
{
"text":"string4"
}
],
"no":[
{
"text":"string6"
},
{
"text":"string7"
}
]
};
let badJson ={
"id": "12345",
"br":{
"text":"string1"
},
"en":{
"text":"string2"
},
"ja":[
{
"text":"string3"
},
{
"text":"string4"
}
],
"no":[
{
"text":"string6"
},
{
"text":"string7"
}
],
"nt": "not_object_or_array"
};
async function run() {
let db = await MongoClient.connect('mongodb://localhost:27017/exampleDb');
let dbo = db.db('mydb');
let collections = await dbo.collections();
let collectionsNames = collections.map(c => c.s.name);
if (collectionsNames.includes(collectionName)) {
console.log('dropping collection');
await dbo.collection(collectionName).drop();
}
console.log('creating collection');
await dbo.createCollection(collectionName, {validator: scheme});
let translationCollection = dbo.collection(collectionName);
console.log('this will validate successfully');
await translationCollection.insertOne(goodJson);
console.log('this will raise validation error because: "nt": "not_object_or_array"');
try {
await translationCollection.insertOne(badJson);
} catch(error) {
console.log(error);
}
await db.close();
}
run();