0

MongoDB の使い方を学んでいます。RDBMS/SQL から NoSQL に考え方を変えるには、しばらく時間がかかります。

次のテーブルとクエリを例として使用して、mongrel を使用してこの単純な RDBMS スキーマを実装する方法と、mongodb を使用してクエリを実装する方法を誰かが説明できることを願っています。

CREATE TABLE tag_category (id INT NOT NULL, name VARCHAR(32) );
CREATE UNIQUE INDEX idxu_tag_cat ON tag_category(name);

INSERT INTO tag_category(1, 'books');
INSERT INTO tag_category(3, 'music');
INSERT INTO tag_category(4, 'food');


CREATE TABLE tag (id INT NOT NULL, 
                  categ_id INT REFERENCES tag_category(id),
                  tagval   VARCHAR(32) NOT NULL
                 );

INSERT INTO tag (1,1,'romance');
INSERT INTO tag (2,1,'scifi');
INSERT INTO tag (3,1,'thriller');
INSERT INTO tag (4,2,'rap');
INSERT INTO tag (5,2,'country');
INSERT INTO tag (6,2,'jazz');
INSERT INTO tag (7,2,'classical');
INSERT INTO tag (8,3,'Chinese');
INSERT INTO tag (9,3,'Italian');
INSERT INTO tag (10,3,'French');
INSERT INTO tag (11,3,'South African');


CREATE TABLE item (id INT,
                  entry_date DATE NOT NULL, 
                  name VARCHAR(32) );
CREATE UNIQUE INDEX idxu_item ON item(name);

INSERT INTO item (id, entry_date, name) VALUES(1, '2011-01-01', 'A love supreme');
INSERT INTO item (id, entry_date, name) VALUES(2, '2011-01-01', 'A kind of blue');
INSERT INTO item (id, entry_date, name) VALUES(3, '2011-02-01', 'Believe the hype');
INSERT INTO item (id, entry_date, name) VALUES(4, '2011-01-01', 'Raising Hell');
INSERT INTO item (id, entry_date, name) VALUES(5, '2011-01-01', 'The Chronic');
INSERT INTO item (id, entry_date, name) VALUES(6, '2011-02-01', 'Blue Danube');
INSERT INTO item (id, entry_date, name) VALUES(7, '2011-01-01', 'Schubert Sonata in B flat');
INSERT INTO item (id, entry_date, name) VALUES(8, '2011-01-01', 'Also Sprach Zarathrustra' );
-- ...

CREATE TABLE item_tag (id INT, 
                       item_id INT REFERENCES tag(id),
                       name VARCHAR(32) );

-- INSERT INTO item_tag (id, item_id, name) VALUES () ....

クエリ

簡潔にするために、1 つのクエリについて説明します。これは、(できれば) 遭遇すると予想されるユース ケース シナリオのほとんどを網羅しています。以下のクエリは、SQL を使用して実装するのは簡単です。mongrel では、その方法がよくわかりません。

  • '2011-01-01' より後のエントリ日付を持つ (音楽カテゴリの) RAP またはクラシックのいずれかとしてタグ付けされたすべてのアイテムをフェッチします。

私の質問を要約するには:

  1. 上記のスキーマを mongodb で実装できるように「移植」するにはどうすればよいですか
  2. 上記のクエリで説明したように、mongodb API を使用してアイテムをリクエストするにはどうすればよいですか?

私は Python と PHP の両方に精通しているため、PHP または Python API のいずれかを使用したソリューションがあれば素晴らしいと思います (私は Python に偏っていますが)。

4

1 に答える 1

2

ドキュメント スキーマの優れた点は、リレーショナルからドキュメント スキーマに変換する必要がないことです。すべてを単独で考えることができます。コレクションに対して行うクエリを検討してから、選択した言語でデータを操作する方法を検討してください。

各ドキュメントがアイテムを表す単一のコレクションのようなものを考えます。各項目には、名前、ID、エントリの日付、場合によってはカテゴリ、およびタグの配列を含めることができます。別のタグのように、カテゴリをタグの配列に入れることも検討するかもしれません。それは、クエリと、保存するアイテムがどのように異なるかによって異なります (食品と音楽は、おそらく別のカテゴリ フィールドを必要とします)。

カテゴリを独自のフィールドに保持すると、ドキュメントは次のようになります。

{
    "_id" : 1,
    "entry_date" : ISODate("2011-01-01T05:00:00Z"),
    "title" : "A love supreme",
    "category" : "music",
    "tags" : [
        "jazz",
        "American"
    ]
}

これをタグとして使用すると、次のようになります。

{
    "_id" : 1,
    "entry_date" : ISODate("2011-01-01T05:00:00Z"),
    "title" : "A love supreme",
    "tags" : [
        "music",
        "American",
        "jazz"
    ]
}

クエリを実行するには、必要findな条件を組み合わせて実行するだけです。1 つの場合は次のようになります。

db.items.find({entry_date:{$gt:new Date(2011,0,1)},
                tags:{$in:["rap","classical"]}})

技術的には、これらのタグが映画などにある場合は追加できcategory:"music"ます。

2 番目のケースでは、次のようになります。

db.items.find({entry_date:{$gt:new Date(2011,0,1)}, 
               tags:"music",tags:{$in:["rap","classical"]}})

タグ配列にマルチキー インデックスを設定でき、MongoDB は複合インデックスをサポートしているため(タグと entry_date で定期的にクエリを実行する場合)、これは非常に効率的なクエリになります。

于 2012-06-17T18:12:22.483 に答える