我有一个邮件存档设置,它运行以下查询,不会返回任何结果。它只是连续运行。以下查询是否有任何问题
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
答案 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"} ]
} )
由于除了其中一个字段之外的所有字段都可以是多个电子邮件地址,我建议您将cc
和to
拆分为一系列电子邮件地址,例如:
{
_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}
]
}