3

インデックスを作成するフィールドの 1 つに特定の値がある場合にのみ、コレクションの一部のドキュメントをインデックスに登録することはできますか?

例を挙げて説明しましょう:

コレクション「posts」には何百万ものドキュメントがあり、すべて次のように定義されています。

    {
        "ネットワーク": "network_1",
        "ブログ名": "ブログ名_1",
        "post_id": 1234,
        "post_slug": "abcdefg"
    }

投稿の分布が network_1 と network_2 で均等に分割されていると仮定しましょう

私のアプリケーションは、「ネットワーク」の値に基づいてクエリのタイプを選択することがよくあります (ただし、両方のネットワークからのデータが必要になる場合もあります)。

例えば:

www.test.it/network_1/blog_1/**postid**/1234/
 -> db.posts.find ({network: "network_1" blogname "blog_1", post_id: 1234})

www.test.it/network_2/blog_4/**slug**/aaaa/
 -> db.posts.find ({network: "network_2" blogname "blog_4" post_slug: "yyyy"})

2 つの個別のインデックス (network / blogname / post_id および network / blogname / post_slug) を作成することもできますが、インデックス内のデータの 50% がまったく使用されないため、RAM を大量に浪費することになります。

「フィルタリングされた」インデックスを作成する方法はありますか?

例: (WHERE パラメータに注意してください)

db.posts.ensureIndex ({network: 1 blogname: 1, post_id: 1}, {where: {network: "network_1"}})

db.posts.ensureIndex ({network: 1 blogname: 1, post_slug: 1}, {where: {network: "network_2"}})
4

4 に答える 4

3

実際、MongoDB 3.2+ では可能です。partialFilterExpression と呼ば 、作成されるインデックスに基づいて条件を設定できます。

db.users.createIndex({ "userId": 1, "project": 1 }, 
{ unique: true, partialFilterExpression:{ 
  userId: { $exists: true, $gt : { $type : 10 } } } })

部分インデックスのドキュメントを参照してください

于 2016-03-03T12:33:32.610 に答える
1

MongoDB v3.2 では、部分インデックスがサポートされています。ドキュメント: https://docs.mongodb.org/manual/core/index-partial/

于 2016-02-03T01:31:50.363 に答える
0

可能ですが、ドキュメントに冗長性を作成し、検索クエリを書き直す必要があり、検索クエリを完全一致に制限する回避策が必要です。

MongoDB は、特定のフィールドが存在するドキュメントのみをインデックス化するスパース インデックスをサポートしています。この機能を使用して、インデックスを作成するドキュメントにのみこのフィールドを追加することで、コレクションの一部のみをインデックスに登録できます。

悪いニュースは、スパース インデックスには 1 つのフィールドしか含めることができないということです。ただし、このフィールドには複数のフィールドを持つオブジェクトを含めることもできるため、検索するすべてのデータをこのフィールドに格納することができます。

これを行うには、検索するフィールドを持つオブジェクトを含む、含まれるドキュメントに新しいフィールドを追加します。

{
    "network": "network_1",
    "blogname": "blogname_1",
    "post_id": 1234,
    "post_slug": "abcdefg"
    "network_1_index_key": {
        "blogname": "blogname_1",
        "post_id": 1234
    }
}

ensureIndex コマンドは、フィールド network_1_index_key にインデックスを付けます。

 db.posts.ensureIndex( { network_1_index_key: 1 }, { sparse: true } )

このインデックスを使用することになっている検索クエリは、フィールド network_1_index_key の正確なオブジェクトをクエリする必要があります。

 db.posts.find ({ 
                    network_1_index_key: { 
                        blogname: "blogname_1", 
                        post_id: 1234 
                    } 
                })

これを行うことは、インデックスを作成するドキュメントがコレクションのごく一部である場合にのみ意味があります。約半分になったら、通常のインデックスを作成してそのまま使用します。ドキュメントのサイズが大きくなると、インデックス サイズの縮小によるメリットが軽減される可能性があるからです。

于 2013-08-29T09:29:12.743 に答える