我有一个猫鼬模式:
models / profile.js
var mongoose = require("mongoose");
var passportLocalMongoose = require("passport-local-mongoose");
var profileSchema = new mongoose.Schema({
username: String,
complete: { type: Boolean, default: false },
email: { type: String, default: "" },
city: { type: String, default: "" }
}, { discriminatorKey: 'accountType' });
profileSchema.plugin(passportLocalMongoose);
module.exports = mongoose.model('Profile', profileSchema);
具有两个与之相关的鉴别符:
models / finder.js
var Profile = require('./profile');
var Finder = Profile.discriminator('finder', new mongoose.Schema({
position: { type: String, default: "" },
skills: Array
}));
module.exports = mongoose.model("Finder");
models / helper.js
var Profile = require('./profile');
var Helper = Profile.discriminator('helper', new mongoose.Schema({
jobTitle: { type: String, default: "" },
lastPosition: { type: String, default: "" }
}));
module.exports = mongoose.model("Helper");
我正在一个快速框架中使用它,并且在一页上(如下所示),我要遍历Profile
中的键/值对以构建表。
我想保留在Schema中指定的顺序,以使页面之间的表顺序保持一致。
是否可以在创建架构时定义排序顺序?
这是我制作表的profile.ejs
文件:
<table class="table profile-display">
<tbody>
<% for(var key in profile.toObject({versionKey: false})) { %>
<% if (key != '_id') { %>
<% if (profile[key].length === 0){ %>
<tr class="incomplete-warning table-rows">
<% } else { %>
<tr class="table-rows">
<% } %>
<td class="key-text"><%=key.toUpperCase()%>:</td>
<td><%=profile[key]%></td>
</tr>
<% } %>
<% } %>
</tbody>
</table>
请告知我是否可以提供更多信息
答案 0 :(得分:1)
每种浏览器对对象排序的处理方式都不同。我建议返回一个JSON对象,该对象映射具有排序值或类似值的架构,并在profile.ejs
模板上进行迭代。然后,您可以随意映射猫鼬输出键中的值。
{
1 : 'username',
2 : 'type',
3 : 'complete',
4 : 'email',
5 : 'city',
6 : 'position',
7 : 'skills'
}
或数组
[
'username',
'type',
'complete',
'email',
'city',
'position',
'skills'
]
然后,您可以根据对象的值或数组映射架构。我喜欢在这种情况下使用数组,因为仅使用索引键就可以更轻松地进行迭代。这取决于您的用法和目的。
希望有帮助。
更新:要最小化两次对模式进行硬编码,您可以创建一个对象,该对象按模式值排序。
代码示例。
// Construct your object
var objSchema = {
obj1 : {
schema : { type: String },
order : 2
},
obj2 : {
schema : { type: String },
order : 3
},
obj3 : {
schema : { type: String },
order : 1
}
}
// Function to construct your schema object and sort array
function mapSortSchema(objs) {
var result = {
schema : {},
order : []
}
for (var obj in objs) {
result.schema[obj] = objs[obj].schema;
result.order.push({
'key': obj,
'order': objs[obj].order
});
}
result.order.sort(function(a, b) {
return a.order - b.order;
});
return result;
}
现在您有了猫鼬的架构和模板的顺序。
var mapSchema = mapSortSchema(objSchema);
// You can now use this with your mongoose schema
var forMongooseSchema = mapSchema.schema;
// result {obj1 : { type: String }, obj2 : { type: String }, obj3 : { type: String }}
// You can now use this to loop through your template
var forTemplateLoop = mapSchema.order;
// result [{key: "obj3", order: 1}, {key: "obj1", order: 2}, {key: "obj2", order: 3}]
还没有用猫鼬测试过它,但是它将为您提供基本的想法,您可以根据需要改进功能。希望对您有所帮助。
答案 1 :(得分:1)
您可以使用retainKeyOrder
默认情况下,猫鼬会反转文档中的键顺序以优化性能。例如,new Model({ first: 1, second: 2 });
实际上将以{ second: 2, first: 1 }
的形式存储在MongoDB中。这种行为被认为已弃用,因为它具有许多意外的副作用,包括使_id字段是对象的文档难以操作。
猫鼬> = 4.6.4为模式提供了一个retainKeyOrder
选项,可确保猫鼬将始终保持对象键的正确顺序。
var testSchema = new Schema({ first: Number, second: Number }, { retainKeyOrder: true });
var Test = mongoose.model('Test', testSchema);
Test.create({ first: 1, second: 2 }); // Will be stored in mongodb as `{ first: 1, second: 2 }`
参考文献:
https://github.com/Automattic/mongoose/issues/1514 https://mongoosejs.com/docs/4.x/docs/guide.html#retainKeyOrder