mongodb查询不断运行

时间:2012-08-28 10:33:45

标签: email mongodb centos

我有一个邮件存档设置,它运行以下查询,不会返回任何结果。它只是连续运行。以下查询是否有任何问题

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 个答案:

答案 0 :(得分: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 :(得分:2)

这种情况通常发生的原因是查询中存在速度问题。

您正在使用嵌套的$或者带有索引不友好的正则表达式。

现在没有预先设定的正则表达式不使用索引(http://www.mongodb.org/display/DOCS/Advanced+Queries#AdvancedQueries-RegularExpressions)并强制进行全表扫描。嵌套的$或子句也不使用索引:https://jira.mongodb.org/browse/SERVER-3327因此您的查询正在扫描可能非常非常大的表。

由于它是一个邮件存档设置,我会说它可以扫描数百万个文档。这就是为什么你没有得到回应而且查询只是“永远”运行。

您可以尝试稍微更改架构以提高性能。首先,您可以省略嵌套的$或者您可以在邮件的标题字段中拆分电子邮件地址以进行搜索,这样您就可以查询更多信息:

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每个查询只能使用一个索引。

这不仅应该返回一个响应,而且不应该杀死你的服务器,并且应该具有超高性能和可扩展性(主要是,可能会做更多的改进)。

修改

好的澄清一下。

您需要引用搜索字符串,如下所示:

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

由于除了其中一个字段之外的所有字段都可以是多个电子邮件地址,我建议您将ccto拆分为一系列电子邮件地址,例如:

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

这当然只是一个示例架构,您需要使用它来获得您想要的内容,但它应该让您走上正确的轨道。

答案 2 :(得分:0)

你错过了大括号。

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

答案 3 :(得分:0)

尝试以下查询。

  

db.content.find({$或:[{“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}
    ]
}