搜索和CMS使用的最有效的JSON / mongodb文档结构是什么?

时间:2012-06-18 21:59:56

标签: php json mongodb

我正在研究一种文档结构,可以在保持可重建结构的同时轻松搜索。我的意思是文档本身包含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"
    }
}   
}

最好的方法是什么?

我极有可能使整个事情变得复杂,并且在我面前有一个简单的解决方案。

1 个答案:

答案 0 :(得分:2)

很好的问题,我发现自己已经摸不着头脑了一段时间。 我将简要介绍一下我所做的事情,但简而言之:是的,请将这些东西分开。我走得更远了,但话又说回来,我可能还有其他一些要求。

请考虑以下事项。

  • Entity可以是从产品到Blogpost的任何内容(由其角色定义。实体可以有多个角色)。
  • Entity有很多Facts
  • 关于标题,描述,slug,英雄形象,作者等实体的所有已知信息都将保存为Fact到该实体。
  • 所有写入操作仅适用于Facts和事实。 (换句话说,应用程序的编辑部分只关注事实,因为事实适用于任何类型的页面,我的编辑代码(当前实现为模态)适用于任何类型的页面)
  • Facts可以是任何给定类型,但必须在FactSchema中定义该类型。 CMS允许动态创建Factschema,从而启用新类型的事实。
  • 可以编辑事实的方式(比如像每个开放时间段有多个下拉菜单的开放时间)在呈现方式上可能完全不同。因此,我需要变压器的可能性(写入和读取之间)。现在,您可能不需要这样做,但这导致了以下内容:
  • Facts永远不会直接用于显示(从而读取)页面。相反,当事实处于编辑模式时,它们只是懒惰地加载。这样可以节省大量的带宽,因为很多东西,比如历史,正在进行的更改,允许编辑角色等都可以用事实保存
  • 要使facts可供阅读,每个实体都有.c(已计算)属性。创建/更改时的每个fact都会以事实名称作为该属性下的键保存(如果已定义,则应用变换器。)
  • 当前渲染方法是在将生成的JSON抛出到服务器端模板引擎进行渲染之前,在我的对象中展平.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]
}

我必须说这很有效。心连心。