2017-05-22 10 views
0

NoSQLに関しては初心者ですので、MongoDBで学習する過程でヘルプデスクアプリケーションを作成することにしました。さて、データモデルを設計するには、私は次のように私がモデル化したユーザーとチケットを持っています。私が参照して、このに従うことをしようとしているMongoose - 複数のコレクションからの問い合わせ

User 
---- 
|- mid (member id, String) 
|- name (user name, String) 
|- mail (e-mail, String) 
\_ pass (md5 hashed password, String) 

、チケットはそれらを作成しても、チケットに返信しているユーザーへのユーザーを参照します。私はそれを次のように構成します:

Ticket 
------ 
    |- tid  (ticket id, String) 
    |- title (title of ticket, String) 
    |- status (status of ticket, String) 
    |- replies (embedded replies doc, [{ mid: ..., msg: ... }]) 
    |- assignee (whom the topic is assigned to, String, refers to users) 
    \_ priority (priority level of the ticket, 1-5, Number) 

今私はすべての開いたチケットのリストをユーザに表示したいと思います。次のように:これは、今まで十分にシンプルに見えますが、ここでdataがオープンの配列です

tickets.find({ "status": "open" }, (err, data) => 
{ 
    if (err) 
    { 
     console.error(err); 
     res.json({ 
      "success": false, 
      "message": "Failure to get from database" 
     }); 
    } 
    else 
    { 
     // TODO: Convert the "mid" references in the data 
    } 
}); 

| Title     | Num Replies | Assignee | Author | Priority | 
|------------------------|-------------|----------|--------|----------| 
| Unblock this URL  | 5   | SHC  | ABC |  5 | 
| Install MS Office here | 2   | STC  | XYZ |  4 | 
           ... 

私はオープン、このコードを持つことをすべてのチケットを取得しましたチケットは、authorassigneeのフィールドをメンバーIDとして使用します。メンバーの名前が必要です。

もちろん、メンバー名を見つけるために別のクエリを実行することもできますが、100個の公開チケットがあると仮定すると、201クエリが得られますが、これはクールではありません。

$inクエリを使用してDBからユーザーオブジェクトを取得し、すべてのチケットをループして得られた結果を使用してユーザーオブジェクトの配列を作成することで、この問題を最適化しようとしましたこれはわずか2クエリになります。それは動作しますが、どのように適切にアプローチするのか、そして何らかのハックがないことを知りたいのです。 MySQLの背景から来る

は、私は、MySQLでの単一のクエリでこれをやっているだろう:

select t.tid, t.title, t.priority, a1.name, a2.name 
    from tickets t, users a1, users a2 
    where a1.mid = t.assignee and 
      a2.mid = t.author; 

私はマングースとMongoDBのクエリでは、この種のアプローチはどうすればよいですか。

答えて

1

MySQLのクエリが使用しています参加 - あなたはどちらのMongoDBではサポートされていません発見したとして。

いくつかのオプションがありますが、そのうちの1つはすでに提供しています。

、個別のユーザーの配列を作成するクエリ内の$を使用してDB からユーザーオブジェクトを取得し、サーバーにそれらをマッピングするために得た結果を使用して、すべてのチケットをループと だけにこれを作ります2 クエリ

...私には悪くはありません。その後

var ticketSchema = Schema({ 
    assignee : { type: String, ref: 'User' }, 
    title : String, 
    //etc... 
}); 

、コール移入:

tickets.find({ "status": "open" }) 
    .populate('assignee') 
    .exec(err, data) => 
    { 
     if (err) 
     { 
      console.error(err); 
      res.json({ 
       "success": false, 
       "message": "Failure to get from database" 
      }); 
     } 
     else 
     { 
      // TODO: Convert the "mid" references in the data 
     } 
    }); 

。なお、下のあなたが好きなものにあなたのticketスキーマを変更する必要がありますhttp://mongoosejs.com/docs/populate.html

-

第二に、populateを使用していますフード、これは実際には複数のクエリをラップしています - しかし、これは気にしないでください - これNoSQLとのトレードオフが受け入れられています。

"ハッキー"の仕組みが働いているなら、私はそれを固執することをお勧めします - それは実際にはハックではなく、単にJOINの欠点に対する回避策です。

+0

ありがとう@Alex、私はpopulateオプションを使用しましたが、仮想スキーマのメンバーがありました。 –

関連する問題