0

メール アーカイブのセットアップがあり、結果を返さない次のクエリを実行します。継続的に実行されるだけです。次のクエリに何か問題がありますか

query:{ $or: [ { $or: [ { rcpt_to: /vpadmin@vp.local/i }, { to: /vpadmin@vp.local/i }, { cc: /vpadmin@vp.local/i } ] } ] }

結果はこのようなものですか?

[
    {
        "$or" : [
            {
                "rcpt_to" : /vpadmin@vp.local/i
            },
            {
                "to" : /vpadmin@vp.local/i
            },
            {
                "cc" : /vpadmin@vp.local/i
            }
        ]
    }
]

メール アーカイブ アプリケーションは、動作して結果を返すログに次のように表示します。この検索は日付で行われます

Tue Aug 28 13:00:40 [conn3] query enkive.userWorkspaces ntoreturn:1 idhack  reslen:152 0ms
Tue Aug 28 13:00:40 [conn3] query enkive.workspaces ntoreturn:1 idhack  reslen:567 0ms
Tue Aug 28 13:00:40 [conn3] insert enkive.searchQueries 0ms
Tue Aug 28 13:00:40 [conn3] insert enkive.searchResults 0ms
Tue Aug 28 13:00:40 [conn3] query enkive.workspaces ntoreturn:1 idhack  reslen:567 0ms
Tue Aug 28 13:00:40 [conn3]   running multiple plans
Tue Aug 28 13:00:40 [conn3] update enkive.workspaces  query: { _id: ObjectId('502b861ee4b04443c5db0481'), CreationDate: new Date(1345029662391), ModifiedUpdate: new Date(1346155131079), Creator: "enkive", WorkspaceName: "Default Workspace", SearchResults: [ "50334ba3e4b06e22baa0f244", "50334bbce4b06e22baa0f247", "50334be0e4b06e22baa0f24a", "5034f31fe4b06e22baa0f2e1", "503c9b73e4b002566417e868", "503cb27be4b002566417e86b", "5034f298e4b06e22baa0f2cc", "50334c72e4b06e22baa0f259", "5034f334e4b06e22baa0f2e4", "503c9b37e4b002566417e862", "503c9b62e4b002566417e865", "5035f329e4b0f6af52a5bb6c" ] } 0ms
Tue Aug 28 13:00:40 [conn3] query enkive.searchResults ntoreturn:1 idhack  reslen:202 0ms
Tue Aug 28 13:00:40 [conn3] query enkive.searchResults ntoreturn:1 idhack  reslen:202 0ms
Tue Aug 28 13:00:40 [conn3]   running multiple plans
Tue Aug 28 13:00:40 [conn3] update enkive.searchResults  query: { _id: ObjectId('503cb2e8e4b002566417e870'), ExecutionTimestamp: new Date(1346155240232), ExecutedBy: "enkive", SearchResults: {}, Status: "QUEUED", SearchQueryId: "503cb2e8e4b002566417e86f", IsSaved: false } 0ms
Tue Aug 28 13:00:40 [conn3] query enkive.emailMessages reslen:6496 nreturned:2 0ms
Tue Aug 28 13:00:40 [conn3] insert enkive.auditLog 0ms
Tue Aug 28 13:00:40 [conn3] query enkive.searchResults ntoreturn:1 idhack  reslen:203 0ms
Tue Aug 28 13:00:40 [conn3]   running multiple plans
Tue Aug 28 13:00:40 [conn3] update enkive.searchResults  query: { _id: ObjectId('503cb2e8e4b002566417e870'), ExecutionTimestamp: new Date(1346155240237), ExecutedBy: "enkive", SearchResults: {}, Status: "RUNNING", SearchQueryId: "503cb2e8e4b002566417e86f", IsSaved: false } 0ms
Tue Aug 28 13:00:40 [conn3] query enkive.emailMessages ntoreturn:1 idhack  reslen:2226 0ms
Tue Aug 28 13:00:40 [conn3] insert enkive.auditLog 0ms
Tue Aug 28 13:00:40 [conn3] query enkive.emailMessages ntoreturn:1 idhack  reslen:4306 0ms
Tue Aug 28 13:00:40 [conn3] insert enkive.auditLog 0ms

@sammaya あなたが私にくれたものを実行すると、次のようになります

> db.emailMessages.find( { $or : [ {"rcpt_to" : vpadmin@vp.local}, {"cc" : vpadmin@vp.local}, {"to" : vpadmin@vp.local} ]} );
Tue Aug 28 17:26:10 SyntaxError: missing } after property list (shell):1
4

4 に答える 4

2

これが通常発生する理由は、クエリ内の速度の問題が原因です。

ネストされた $or を、インデックスに適していない正規表現で使用しています。

現在、前に保留されている正規表現はインデックスを使用せず ( http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-RegularExpressions )、完全なテーブル スキャンを強制します。ネストされた $or 句もインデックスを使用しません: https://jira.mongodb.org/browse/SERVER-3327そのため、クエリは非常に非常に大きなテーブルになる可能性があるものをスキャンしています。

これはメール アーカイブのセットアップであるため、何百万ものドキュメントをスキャンできると言えます。これが、応答が得られず、クエリが永久に「実行」される理由です。

スキーマを少し変更して、パフォーマンスを向上させることができます。まず、ネストされた $or を省略できます。おそらく、検索するメールのヘッダー フィールド内でメール アドレスを分割して、次のようなクエリを作成できます。

db.emailMessages.find( { 
    $or : [ {"rcpt_to" : vpadmin@vp.local},
            {"cc" : vpadmin@vp.local}, 
            {"to" : vpadmin@vp.local} ]
} ) 

ここでクエリを実行するフィールドは、電子メール アドレスの配列である可能性があり、これは問題なく機能します。この後、@Macdiesel が言うように、適切なインデックスを設定する必要があります。

db.emailMessages.ensureIndex( { rcpt_to: 1, cc: 1, to: 1 }, { background: true } );

MongoDB はクエリごとに 1 つのインデックスしか使用できないため、ここで複合インデックスを作成します。

これは、応答を返すだけでなく、サーバーを停止させず、非常にパフォーマンスが高く、スケーラブルでなければなりません (ほとんどの場合、さらに改善することができます)。

編集

わかりましたので、いくつか説明します。

次のように検索文字列を引用符で囲む必要があります。

db.emailMessages.find( { 
    $or : [ {"rcpt_to" : "vpadmin@vp.local"},
            {"cc" : "vpadmin@vp.local"}, 
            {"to" : "vpadmin@vp.local"} ]
} ) 

これらのフィールドの 1 つを除くすべてが複数のメール アドレスになる可能性があるため、次のようなメール アドレスの配列にcc分割することをお勧めします。to

{
    _id: {},
    rcpt_to: "vpadmin@vp.local",
    cc: ["me@awesome.com", "you@kool.com"],
    to: ["another@notsokool.com"],
    message: "yo"
}

もちろん、これは単なるスキーマの例であり、必要なものを正確に取得するには、それをいじる必要がありますが、正しい方向に進むはずです。

于 2012-08-28T14:46:30.517 に答える
2

このクエリが遅い理由について話しましょう。

データセットの大きさは?

これらのフィールドのいずれかにインデックスはありますか?

クエリに or ステートメントと正規表現があるため、特にデータ セットがかなり大きい場合は、実行に時間がかかる場合があります。

「二度と戻ってこない」と言う前に、どれくらい待っていますか?

クエリをそのように書き直すことはできませんか?

db.emailMessages.find( { $or : [ {"rcpt_to" : /vpadmin@vp.local/i},
                                 {"cc" : /vpadmin@vp.local/i}, 
                                 {"to" : /vpadmin@vp.local/i} 
                               ] 
                        } 
                      ) 

また、これらのフィールドにいくつかのインデックスを追加してみてください:

db.emailMessages.ensureIndex( { rcpt_to: 1, cc: 1, to: 1 }, { background: true } )

また、クエリ言語を使用したりインデックスを追加したりする代わりに、mongo map/reduce ジョブを作成してこのクエリを実行することを検討することもできます。いずれにせよ、このデータを照会するには、完全なテーブル スキャンを実行する必要があります。map reduce は、これを処理するためのはるかに優れた方法です。

mongodb map/reduce へのリンクは次のとおりです: http://www.mongodb.org/display/DOCS/MapReduce

編集:

彼が正しいので、別の回答ごとにインデックスの作成を変更しました。mongoはクエリに1つのインデックスのみを使用します。

于 2012-08-28T14:24:19.407 に答える
0

右中括弧がありません。

query:{ $or: [ { $or: [ { rcpt_to: /vpadmin@vp.local/i }, { to: /vpadmin@vp.local/i }, { cc: /vpadmin@vp.local/i } ] } ]}
于 2012-08-28T10:50:58.267 に答える
0

次のクエリを試してください。

db.content.find({$or : [{"rcpt_to" : /vpadmin@vp.local/i},{"cc" : /vpadmin@vp.local/i}, {"to" : /vpadmin@vp .local/i}]});

{$or : 
    [
        {"rcpt_to" : /vpadmin@vp.local/i},
        {"cc" : /vpadmin@vp.local/i}, 
        {"to" : /vpadmin@vp.local/i}
    ]
}
于 2012-08-28T11:18:27.183 に答える