22

NoSQL データベースを使用して node.js アプリケーションの分類構造 (地理用語) を実装したいと考えています。私は MySQL で同様の分類構造を持っていましたが、先に進んで何か新しいことを学ぶ時が来たので、別のアプローチを試して、テスト アプリに NoSQL (ドキュメント指向) を使用することにしました。分類構造は単純です。5 つの異なるレベルがあります: 国 (イギリス) → 地域 (イングランド) → 郡 (マージーサイド) → 都市/町/村 (リバプール) → 都市の一部 (トクステス)

明らかな選択はツリー構造を使用することですが、悪魔は詳細にあります。歴史的に、一部の市や町は他の郡に属していました。そのアイデアは、特定の都市や町で生まれた人にそれらの用語でタグを付け、後でジオタグでフィルタリングすることでした。そのため、一部の人が生まれたときにリバプールやマンチェスター (とりわけ) がランカシャーの一部であったという事実を尊重する必要があります。 . そうしないと、ユーザーが geo フィルターで取得する結果が正しくなくなります。

例: John Doe は、1957 年にブラックバーン (ランカシャー) で生まれました。Paul Brown は、1960 年にリバプール (ランカシャー、現在のマージーサイド) で生まれました。ジョージア・ドウ(旧姓ジョーンズ)は、5年後にウィラル(チェシャー、現在のマージーサイド)で生まれました。息子のリンゴは、1982 年にリバプール (当時はマージーサイド) で生まれました。

ジョンはランカスター出身、ポールはランカスター出身でマージーサイド出身、ジョージアはチェシャーとマージーサイド出身、リンゴはマージーサイド出身です。そのため、郡で検索するときに、それに応じて分類する必要があります。しかし、現代の国の構造に従った単純な 1 対多の構造では、本来あるべきようにフィルタリングされることはありません。

NoSQL (まず第一にドキュメント指向) ソリューションを使用して、その構造の複雑さを考慮してコレクションを実装する方法は? 私はそれをグーグルで検索し、スタック*についていくつかの調査を行いましたが、次に何をすべきかまだわかりませんでした. 私の意見では、それを解決する方法がいくつかあります。

  1. SQL に似たデータ構造を使用します。

    {
        {'name': 'United Kingdom', 'unique_id': 1},
        {'name': 'England', 'unique_id': 2, 'parents': [1]},
        {'name': 'Merseyside', 'unique_id': 3, 'parents': [2]},
        {'name': 'Lancashire', 'unique_id': 4, 'parents': [2]},
        {'name': 'Liverpool', 'unique_id': 5, 'parents': [3, 4]},
    }
    
  2. いくつかの参照でツリー構造を使用します。

    {    
        {'name': 'United Kingdom', 'unique_id': 1
            {'name': 'England', 'unique_id': 2]
                {'name': 'Merseyside', 'unique_id': 3]
                    {'name': 'Liverpool', 'unique_id': 5, 'alternate_parents': [4]},
                },
                {'name': 'Lancashire', 'unique_id': 4},
            },
        },
    }
    
  3. 参照のないツリー構造 (1 対多) を使用し、ドキュメントに「代替の親」タグを手動で追加します。

    {    
        {'name': 'United Kingdom', 'unique_id': 1
            {'name': 'England', 'unique_id': 2]
                {'name': 'Merseyside', 'unique_id': 3]
                    {'name': 'Liverpool', 'unique_id': 5},
                },
                {'name': 'Lancashire', 'unique_id': 4},
            },
        },
    }
    
  4. SQL に固執します。

  5. データベースを使用しない分類法を実装してみてください。

その点についてアドバイスをお願いします。私はNoSQLの初心者なので(現在、そのようなデータベースを設計していません)、実際の設計上の問題があります。

そして、私はスタック*に慣れていないので、この投稿で何か間違ったことをした場合は、お気軽に修正してください:) ありがとう!

EDIT @Jonathan answer を解決策として選択しました。特に@Valentynによって提案されたmapReduce機能を使用すると、私のニーズに適していると思います(データベースに保存してそれらの用語でタグ付けするドキュメントが他にもあります)。

ただし、アプリに必要なドキュメント コレクションがない場合は、@Philipp によって提案されたグラフ データベース (ドキュメントではなく関係に基づく) がおそらく最善の解決策です。

4

2 に答える 2

8

あなたのコメントから、「NoSQL」と言うときは「MongoDB」を意味していると思います。一般にNoSQLと呼ばれる、まったく異なるデータベース技術は他にもたくさんありますが、これはあなたが意味しているもののようです。

  1. 分類チェーン全体を取得するには、複数のデータベースクエリを実行する必要がありますが、これは通常避けるべきであるため、お勧めできません。

  2. 3. MongoDB にはドキュメントあたり 16MB の制限があるため、巨大なツリーである単一のドキュメントも良い考えではありません。巨大でモノリシックなドキュメントを作成すると、その限界に達する可能性があります。

MongoDB は、あなたのユースケースにとって最適なソリューションではないかもしれないと思います。グラフデータベースの使用を検討しましたか? MongoDB は、独立した自己完結型のドキュメント用に最適化されています。しかし、グラフ データベースの焦点は、他のエンティティとの関係によって定義されるエンティティが多数あるデータセットにあります。これは、ユースケースによく似ています。

于 2013-01-12T20:20:11.137 に答える
5

まず、基本的な原則に精通していない場合、NoSQLとSQLデータベースのどちらかを選択するのは困難です。これが保存している唯一のデータである場合は、リレーショナル(SQL)を使用してください。より多くのデータ(私が想定している)があり、それがより多くの織り交ぜられたスキーマを必要とする場合は、NoSQLの手を下に置いてください。

複雑になりすぎないように、これについてはリレーショナルルートを使用します...いくつかのコレクションを開始します。1つは国、地域などです。NoSQLデータベースでリレーショナル(SQL)型スキーマを実行することに落胆しないでください。ほとんどの場合、それらは最良の解決策です。

次に、各サブグループに、親を指定するフィールドがあります。

例えば:

{
    {'name': 'United Kingdom'},
    {'name': 'United States'}
}

{
    {'name': 'England', 'parent': 'United Kingdom'},
    {'name': 'California', 'parent': 'United States'}
}

そうすれば、返されたデータが管理不能になるほどデータセットがネストされることはありません。その後、国や対応する地域などを簡単に取得できます。

頑張ってください!

編集:OPの質問に答える:

(まず、MongoDBをお勧めします-これはあらゆる面で優れたソリューションです。)

  1. MongoDBを使い始めると、データがハードドライブに並べて保存されていることに気付くでしょう。このような巨大なレコードを編集すると、ディスクの背面にプッシュされる可能性が高くなり、ハードドライブがスイスチーズのようになります。その時点に到達したら、もう一度それを凝縮するために修理を行う必要があります。また、この方法では、アプリケーションでデータをより簡単に分離できます。つまり、データを処理する必要がある場合でも、オブジェクト全体にデータを適用する必要はありません。世界にはさまざまな場所があるため、大規模なデータセットがあると想定しています。

  2. そのようなことについてはあまり心配しないでください。名前を頻繁に変更する予定がある場合は、親にIDを使用し、子をIDと一致させることができます。ロケーションデータベースを変更する必要はないと思ったので、この方法で実行しました。

  3. 配列ではなく、ネストされたドキュメントを使用して複数の親を格納します。そうすれば、より簡単にクエリとインデックスを作成できます。次の方法を使用します。

    {
        {
            'name': 'England,
            'parent': {
                1: 1,
                568: 1
            }
         }
     }
    

そうすれば、インデックスのアイデアを採用して、db.region.$.568=を見つけることができます。1

于 2013-01-12T02:07:30.593 に答える