-1

次のデータ構造を考慮すると、データベースシステム(rdbmsまたはnosql)に格納されたデータをクエリする方がよいでしょうか。メタデータフィールド内のフィールドはユーザー定義であり、ユーザーごとに異なります。可能な値は、文字列、数値、「日付」、さらには配列です。

var file1 = {
    id: 123, name: "mypicture", owner: 1
    metadata: {
        people: ["Ben", "Tom"],
        created: 2013/01/01,
        license: "free",
        rating: 4
        ...
    },
    tags: ["tag1", "tag2", "tag3", "tag4"]
}

var file2 = {
    id: 155, name: "otherpicture", owner: 1
    metadata: {
        people: ["Tom", "Carla"],
        created: 2013/02/02,
        license: "free",
        rating: 4
        ...
    },
    tags: ["tag4", "tag5"]
}

var file1OtherUser = {
    id: 345, name: "mydocument", owner: 2
    metadata: {
        autors: ["Mike"],
        published: 2013/02/02,
        …       
    },
    tags: ["othertag"]
}

ユーザーは、ファイルを検索/フィルタリングできる必要があります。

  • ユーザー1:「Tom」が「people」配列にあるすべてのファイルを表示する
  • ユーザー1:2013/01/01から2013/02/01の間に「作成された」すべてのファイルを表示する
  • ユーザー1:「ライセンス」「無料」および「評価」が大きい2のすべてのファイルを表示
  • ユーザー2:「2012」で「公開」され、「重要」でタグ付けされたすべてのファイルを表示
  • ..。

結果は、インテリジェントフォルダを使用するOSXで実行できるのと同じ方法でフィルタリングする必要があります。個々のメタデータフィールドは、ファイルがアップロード/保存される前に定義されます。ただし、その後変更される可能性もあります。たとえば、ユーザー1はメタデータフィールドの名前を「people」から「cast」に変更する場合があります。

4

1 に答える 1

0

@WiredPrairieが言ったように、フィールド内のmetadataフィールドは可変に見えます。おそらく、ユーザーが入力したものに依存し、次のものがサポートされています。

ユーザー 1 は、メタデータ フィールド「people」の名前を「cast」に変更できます。

MongoDB は可変インデックスを作成できないため、すべての新しいフィールドmetadataが複合インデックスに追加されると言うだけですが、次のようなキーと値の型構造を行うことができます。

var file1 = {
    id: 123, name: "mypicture", owner: 1
    metadata: [
        {k: people, v:["Ben", "Tom"]},
        {k: created, v:2013/01/01},
    ],
    tags: ["tag1", "tag2", "tag3", "tag4"]
}

これは、フィールド内で と の両方kv動的にインデックスを作成できるようにするための 1 つの方法です。metadata次に、次のようにクエリします。

db.col.find({metadata:{$elemMatch:{k:people,v:["Ben"]}}})

ただし、これにより別の問題が発生します。$elemMatchネストされた要素ではなく、トップレベルで機能します。「Ben」が の 1 つであるすべてのファイルを検索したいと想像してください。ここでpeopleは使用できないため、次の$elemMatchようにする必要があります。

db.col.find({metadata.k:people,metadata.v:"Ben"})

このクエリの差し迫った問題は、MongoDB クエリの方法にあります。metadataフィールドをクエリすると、「k」の 1 つのフィールドは「people」に等しく、「v」のフィールドは「Ben」に等しいと表示されます。

これは複数値フィールドであるため、"Ben" が Peoples リストになくても、別のフィールドに存在するため、metadata実際には間違ったドキュメントを選択するという問題が発生する可能性があります。つまり、このクエリは次のものを取得します。

var file1 = {
    id: 123, name: "mypicture", owner: 1
    metadata: [
        {k: people, v:["Tom"]},
        {k: created, v:2013/01/01},
        {k: person, v: "Ben"}
    ],
    tags: ["tag1", "tag2", "tag3", "tag4"]
}

これを解決する唯一の現実的な方法は、この問題が発生していない別のコレクションに動的フィールドを除外することです。

ただし、これにより新しい問題が発生します。1 回の往復で完全なファイルを取得することはできなくなり、ファイル行とそのユーザー定義フィールドの両方を一度に集約することもできなくなります。全体として、これをドンすることで多くの能力を失います。

そうは言っても、かなりの数のクエリを実行できます。つまり、次のとおりです。

  • ユーザー 1: 「Tom」が「people」配列にあるすべてのファイルを表示する
  • ユーザー 1: 2013/01/01 から 2013/02/01 の間に「作成」されたすべてのファイルを表示
  • ユーザー 1: "license" "free" および "rating" より大きい 2 を持つすべてのファイルを表示する
  • ユーザー 2: 「2012 年」に「公開」され、「重要」とタグ付けされたすべてのファイルを表示する

これらすべては、このスキーマでも可能です。

どちらが優れているかについて-RDBMSまたはNoSQL; ここで言うのは難しいですが、正しく行えば、この構造を照会する際に両方とも非常に優れていると言えます。

于 2013-03-02T13:31:57.520 に答える