1

再構築可能な構造を維持しながら、簡単に検索できるドキュメント構造に取り組んでいます。つまり、ドキュメント自体が、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"
    }
}   
}

最善のアプローチは何ですか?

私が全体を複雑にしすぎている可能性が高く、目の前に簡単な解決策がある可能性があります。

4

1 に答える 1

2

素晴らしい質問です。かなり長い間頭を悩ませていました。私がやったことの簡単な要点を述べますが、要するに:はい、物事を分けてください. もう少し先に進みましたが、もう一度言いますが、他の要件があった可能性があります。

以下を検討してください。

  • 製品からブログ投稿まで何でもかまいません(Entity役割によって定義されます。エンティティは複数の役割を持つことができます)。
  • アンEntityには がたくさんありFactsます。
  • タイトル、説明、スラッグ、ヒーロー画像、作成者など、エンティティに関する既知の情報はすべて、Factそのエンティティに として保存されます。
  • すべての書き込み操作はFactsFacts のみで機能します。(つまり、アプリの編集部分は事実のみを考慮します。事実はあらゆる種類のページで機能するため、私の編集コード (現在はモーダルとして実装されています) はあらゆる種類のページで機能します)
  • Factsは任意の型にすることができますが、その型は で定義する必要がありますFactSchema。CMS を使用Factschemaすると、その場で を作成できるため、新しいタイプのファクトが可能になります。
  • 事実を編集できる方法 (営業時間スロットごとに複数のドロップダウンがある営業時間のようなもの) は、表示方法がまったく異なる場合があります。したがって、トランスフォーマー (書き込みと読み取りの間) の可能性が必要でした。さて、これはあなたには必要ないかもしれませんが、これは私を次のように導きました:
  • Factsページの表示 (したがって読み取り) に直接使用されることはありません。代わりに、ファクトが編集モードの場合にのみ遅延ロードされます。履歴、進行中の変更、許可された編集ロールなどの多くのものが事実とともに保存される可能性があるため、これにより多くの帯域幅が節約されます。
  • 読み取りに使用できるようにするfactsために、各エンティティには.c(計算用の) プロパティがあります。作成/変更時にそれぞれfactがそのプロパティの下のキーとしてファクトの名前で保存されます (定義されている場合はトランスフォーマーを適用します)。
  • .cレンダリングの現在の方法は、結果の JSON をレンダリングのためにサーバー側のテンプレート エンジンにスローする直前に、オブジェクトをフラット化することです。(したがって、すべてのプロパティ.cは、それを含むオブジェクトのプロパティになります)

それはそれについてです。さらに、ZERO プレゼンテーション ロジックはこれらのモデルで定義されており、代わりに Mustache/Hogan テンプレートで定義されています。(プレゼンテーションロジックに関する限り、ロジックのないテンプレートで可能なことを拡張する必要がある場合は、いくつかのJavaScript関数が混在しています)。

で定義されているように、ファクトに対して検索を実行できます/実行する必要があります.c。私はElasticsearchを通してそれをやっていますが。

これらの 3 つのスキーマ宣言 (簡略化) を次に示します (ps: スキーマは 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]
}

これはかなりうまく機能していると言わざるを得ません。H番目。

于 2012-06-19T16:11:11.947 に答える