1

Facebook の彫像では、@ の入力を開始して、ステータスでユーザーにタグを付けることができます。この質問はフロントエンドに関するものではなく、その機能のデータを保存する方法です。mongodb エンティティを文字列で動的に表現するための一般的な方法でこの機能を実現する最善の方法は何ですか。目標は、エンティティが変更された場合、格納された文字列での表現も変更されることです。たとえば、私が持っていたアイデアの1つは次のとおりです。

Post: {
    _id: "48ajsdlfhsdjfkjsljsd"
    name: "Post One",
    text: "@user is the best for liking @thing, and @thing"
    tags: [user:1234, thing:456, thing:789]
}

したがって、この投稿を読み込んで、タグを見て、タグの種類と ID ごとにモデルを読み込んで、文字列を次のように書き換えます。これは効率が悪いようですが、何か良いアイデアはありますか?

4

2 に答える 2

1

あなたの答えはうまくいきますジェフですが、もう少し効率的なものを探していました。私がやったことは、このようにMongoにドキュメントを保存することです

{
    _id: "4bdslakjghjdgkjsh123",
    title: "Post One",
    text: "@ is cool for liking @",
    tags: ["user:4bcasdkasd89", "product:4basfkjafkjlfl"]
}

タグを変換するコードは、メッセージの読み込み後に実行されます。基本的に、タグを使用して、使用するモデルのタイプと、それをロードするための id を認識します。次に、モデルの as_tag メソッドまたは to_s を使用して、値の配列を作成します。この配列は、@ 記号を置き換えるために元の文字列に代入されます。sprintf によく似ています。直訳すると「クリスは自転車好きでかっこいい」

def after_initialize
    tags = self.collect_tags
    tags.each do |value|
      self.text.sub!(/@/, value)
    end
end

def collect_tags
    self.tags.collect do |tag|
        model, id = tag.split(':')
        model[0] = model[0,1].upcase
        m = Models.const_get(model).find(id)
        if(m.respond_to? 'as_tag')
            m.as_tag
        else
            m.to_s
        end
    end
end

ここで効率を改善する方法はありますか?

于 2012-04-22T23:53:43.930 に答える
0

あなたが何をしようとしているのかよくわかりませんが、次のことをお勧めします。

  1. 文字列の「@」タグと MongoDB ドキュメント内のフィールドとの間のマッピングとして機能するドキュメントを作成します。

  2. タグ配列に、実際のデータが保存されているドキュメントの _id 値と、これらのドキュメントでデータを取得するフィールドの両方を識別する標準化されたドキュメントが含まれるように、Post ドキュメントを変更します。

  3. (オプション) Post ドキュメントを変更して、マッピング ドキュメント _id を明示的に含めます。グローバル マッピング ドキュメントがある場合、これは不要ですが、

あなたの例では、マッピング ドキュメントは次のようになります。

Mapping: { _id: "abc..", maps: [{tag:"user", field:"user.person.nickname"}, {tag:"thing", field:"object.name"}] }

投稿文書は次のようになります。

Post: { _id: "48ajsdlfhsdjfkjsljsd",
  name: "Post One",
  text: "@user is the best for liking @thing, and @thing",
  tags: [{tag:"user", docId:"pqr..."}, {tag:"thing", docId:"xzy..."}, {tag:"thing", docId:"mno..."}],
  mapping: "abc..."
}

テキスト文字列を返すには、次の操作を行う必要があります。

  1. Post ドキュメントを読み込む
  2. マッピング ドキュメントを抽出してロードします (このマッピングがグローバルである場合、この手順は必要ありません)。
  3. 基になるデータに対応するすべてのドキュメントを 1 回の読み込みで読み込みます。

    db.posts.find( { _id: { $in : [ "pqr...", "xyz...", "mno..." ] } })

  4. 見つかった各ドキュメントの必須ドキュメント フィールドから値を取得します

  5. タグをフィールド値に置き換えます

この方法では、文字列内のタグの意味を変更する (マッピング ドキュメントを変更する - たとえば、@user をニックネームから実名に変更する) ことと、タグの値を変更する (タグに格納されている docIds を変更する) ことができます。 Post ドキュメント内のリスト) ですが、文字列の生成には少なくとも 4 つの手順が必要です。

この方法では、マッピング ドキュメントにタグが含まれていない場合や、タグ リストがテキスト文字列内のタグの数と同じサイズでない場合は処理されません。

于 2012-04-22T02:22:30.703 に答える