我正在研究一种文档结构,可以在保持可重建结构的同时轻松搜索。我的意思是文档本身包含CMS构建更新文档所需表单所需的信息。
关键是文档的最终结构永远不会被知道,因为它将通过CMS构建/修改。
目标是确保前端内容方法可以快速搜索,同时使CMS能够重建内容以便对其进行管理。我毫不犹豫地使CMS的管理区域更加努力,速度在那里并不那么重要。
以下是一个基本示例
这是一个高度缩写的文件,但它可以说明我的观点。该文档相对容易查询,但它没有关于CMS如何显示它的结构信息。
{
"name" : "Page Name",
"title" : "Page Title",
"description" : "Page Description",
"page_heading" : "New Heading",
"content_body" : "<p>New Content</p>",
"slideshow" :
[
{
"image_title" : "Vacation Hawaii",
"image_file" : "hawaii100.jpg"
},
{
"image_title" : "Vacation Spain",
"image_file" : "Spain200.jpg"
},
]
}
以下是缩写结构数据的示例
这种方法的问题在于查询变得更加困难。
> db.posts.find( { page_heading.value : "example" } )
-
{
"name" : "Page Name",
"title" : "Page Title",
"description" : "Page Description",
"page_heading" :
{
"value" : "This is the page heading",
"type" : "string",
},
"content_body" :
{
"value" : "<p>HTML Content</p>",
"type" : "html_textarea",
},
"slideshow" :
{
"type" :
{
"image_title" : "string",
"image_file" : "file"
},
"value" :
[
{
"image_title" : "Vacation Hawaii",
"image_file" : "hawaii100.jpg"
},
{
"image_title" : "Vacation Spain",
"image_file" : "Spain200.jpg"
},
]
}
}
替代方法
单独的文档,一个用于数据,一个用于模板,似乎是一种可能的解决方案,但稍微增加了后勤复杂性。
链接到模板的内容文档
{
"name" : "Page Name",
"title" : "Page Title",
"description" : "Page Description",
"template" : "document_id",
"page_heading" : "New Heading",
"content_body" : "<p>New Content</p>",
"slideshow" :
[
{
"image_title" : "Vacation Hawaii",
"image_file" : "hawaii100.jpg"
},
{
"image_title" : "Vacation Spain",
"image_file" : "Spain200.jpg"
},
]
}
模板文档
{
"parent" : "document_id",
"page_heading" :
{
"type" : "string",
"required" : true
},
"content_body" :
{
"type" : "html_textarea",
"required" : true
},
"slideshow" :
{
"type" :
{
"image_title" : "string",
"image_file" : "file"
}
}
}
最好的方法是什么?
我极有可能使整个事情变得复杂,并且在我面前有一个简单的解决方案。
答案 0 :(得分:2)
很好的问题,我发现自己已经摸不着头脑了一段时间。 我将简要介绍一下我所做的事情,但简而言之:是的,请将这些东西分开。我走得更远了,但话又说回来,我可能还有其他一些要求。
请考虑以下事项。
Entity
可以是从产品到Blogpost的任何内容(由其角色定义。实体可以有多个角色)。 Entity
有很多Facts
。 Fact
到该实体。 Facts
和事实。 (换句话说,应用程序的编辑部分只关注事实,因为事实适用于任何类型的页面,我的编辑代码(当前实现为模态)适用于任何类型的页面)Facts
可以是任何给定类型,但必须在FactSchema
中定义该类型。 CMS允许动态创建Factschema
,从而启用新类型的事实。 Facts
永远不会直接用于显示(从而读取)页面。相反,当事实处于编辑模式时,它们只是懒惰地加载。这样可以节省大量的带宽,因为很多东西,比如历史,正在进行的更改,允许编辑角色等都可以用事实保存facts
可供阅读,每个实体都有.c
(已计算)属性。创建/更改时的每个fact
都会以事实名称作为该属性下的键保存(如果已定义,则应用变换器。).c
。 (因此,.c
中的所有属性都成为包含对象的属性)就是这样。此外,ZERO表示逻辑在这些模型中定义,这在Mustache / Hogan模板中定义。 (如果我需要扩展无逻辑模板的可能性,那么有几个混合的javascript函数,就目前的情况而言是表示逻辑)。
可以/应该对.c
中定义的事实进行搜索。虽然我是通过Elasticsearch做的。
这是3个架构声明(简化)(p.s:架构在Node.js中,但不应该打扰你)
var fact= new Schema(
{
//_id undefined > defaulting to mongoDB objectid instead
//factschema is looked-up by name
name: { type: String, required: true, index: { unique: false }}
//value can be any type, but for a particular instance the type is restricted as set in FactSchema.valueType
,value: {type: {}, required: true}
,createddate : { type: Date, required: true, default: Date.now, select: false }
}
var entity= new Schema(
facts: { type:[require('./fact')], select:false}
,roles: {type: [String], required: true, index: {unique: false}}
,c: {type: {}} //all calculated stuff based on facts
}
var factSchema= new Schema({
name: { type: String, required: true, index: { unique: true }}
, valueType: { type: {}, required: true} //any type may be defined (simple types but also complex-types which have a ref to their own schema) , fact-instances are checked to adhere to the specified type in pre-save handlers.
,roles: {type: [String], required: true} //roles that are allowed to contain facts based on this factschema
,isMulti: {type: Boolean, required: true }
//format to show edit-mode in.
,formFieldType: {type: String, required: true}
//ACL-stuff
,directChangeRoles: {type: [String]} //i.e: [super, admin,owner]
,suggestChangeRoles: {type: [String]} //ie: [editor]
}
我必须说这很有效。心连心。