Php Mongodb集合不使用多个搜索进行搜索
嗨,我在处理多个字段的搜索时遇到了一个问题。我收集了超过一百万张唱片。当我在单个字段上执行操作时,它会给出一个闪烁的结果。但是,当我尝试使用多个字段时,它会被抛出。我正在尝试使用以下匹配条件进行搜索:名字以“b”开头,姓氏以“on”结尾,电子邮件完全匹配”bwashington@zoombeat.net“ 我的收藏看起来像:Php Mongodb集合不使用多个搜索进行搜索,php,mongodb,Php,Mongodb,嗨,我在处理多个字段的搜索时遇到了一个问题。我收集了超过一百万张唱片。当我在单个字段上执行操作时,它会给出一个闪烁的结果。但是,当我尝试使用多个字段时,它会被抛出。我正在尝试使用以下匹配条件进行搜索:名字以“b”开头,姓氏以“on”结尾,电子邮件完全匹配”bwashington@zoombeat.net“ 我的收藏看起来像: { "_id": ObjectId("5391c81069f6872810004e49"), "salutation": "frau", "date
{
"_id": ObjectId("5391c81069f6872810004e49"),
"salutation": "frau",
"date_of_birth": ISODate("1970-01-01T00:00:00.0Z"),
"first_name": {
"0": {
"value": "Benjamin",
"date_inserted": "2014-06-06 03:54:24",
"date_modified": "2014-06-06 03:54:24",
"sweepstake": {
"sweepstake_id": "535e03888a06f83c12001380",
"sweepstake_url": "http:\/\/localhost\/redlemon\/sweepstakes\/register_user\/1\/53563bd68a06f8941300002b",
"date_inserted": "2014-06-06 03:54:24",
"date_modified": "2014-06-06 03:54:24",
"current_page": "1",
"session_id": "4ef315c35b5a1162eedc37fa109c3c57",
"last_activity": ISODate("2014-06-06T13:45:31.0Z")
}
}
},
"last_name": {
"0": {
"value": "Washington",
"date_inserted": "2014-06-06 03:54:24",
"date_modified": "2014-06-06 03:54:24",
"sweepstake": {
"sweepstake_id": "535e03888a06f83c12001380",
"sweepstake_url": "http:\/\/localhost\/redlemon\/sweepstakes\/register_user\/1\/53563bd68a06f8941300002b",
"date_inserted": "2014-06-06 03:54:24",
"date_modified": "2014-06-06 03:54:24",
"current_page": "1",
"session_id": "4ef315c35b5a1162eedc37fa109c3c57",
"last_activity": ISODate("2014-06-06T13:45:31.0Z")
}
}
},
"email": {
"0": {
"date_inserted": "2014-06-06 03:54:24",
"date_modified": "2014-06-06 03:54:24",
"sweepstake": {
"sweepstake_id": "535e03888a06f83c12001380",
"sweepstake_url": "http:\/\/localhost\/redlemon\/sweepstakes\/register_user\/1\/53563bd68a06f8941300002b",
"date_inserted": "2014-06-06 03:54:24",
"date_modified": "2014-06-06 03:54:24",
"current_page": "1",
"session_id": "4ef315c35b5a1162eedc37fa109c3c57",
"last_activity": ISODate("2014-06-06T13:45:31.0Z")
},
"email_id": "bwashington@zoombeat.net",
"email_optin_flag": "1",
"single_optin_flag": "1",
"double_optin_flag": "0",
"current_status": "active",
"suspicious_flag": NumberInt(0)
}
},
"last_inserted_date": ISODate("2014-06-06T13:54:24.0Z"),
"last_date_modified": ISODate("2014-06-06T13:54:24.0Z")
}
我在“leads”集合中添加了索引,如下所示:
db.leads.ensureIndex({first_name:1},{sparse:true});
db.leads.ensureIndex({"last_name":1});
db.leads.ensureIndex({“email”:1});
db.leads.ensureIndex({"first_name.value":1});
db.leads.ensureIndex({"last_name.value":1});
db.leads.ensureIndex({"email.email_id":1});
当我用currentOp()检查mongodb shell中的查询时,它看起来像:
"query" : {
"$query" : {
"first_name.value" : /^b/i,
"last_name.value" : /on$/i,
"email.email_id" : /^bwashington@zoombeat.net$/i
},
"$orderby" : { "last_inserted_date" : NumberLong(-1) }
}
按多个字段搜索时,查询速度较慢的原因是MongoDB没有(有效地)为查询使用索引 在版本2.6中,MongoDB获得了一个名为的新特性,它可以使用多个索引的交集来完成查询。虽然这个特性很有用,但使用复合索引会得到更好的结果 您还可以通过删除电子邮件上的正则表达式搜索来优化查询,并执行简单的相等性检查,这比正则表达式更快:
{
"email.email_id" : "bwashington@zoombeat.net",
"first_name.value" : /^b/i,
"last_name.value" : /on$/i
}
您可以创建复合索引:
db.coll.ensureIndex({
"email.email_id" : 1,
"first_name.value": 1,
"last_name.value" : 1,
"last_inserted_date" : -1
});
索引中包含上次插入日期,以便MongoDB在排序时可以使用它(如果排序操作消耗的内存超过32MB,则会出现错误)。有关排序数据时使用索引的详细信息,请查看
编辑
由于格式错误,我没有看到文档的正确结构:)添加索引不起作用,因为无法在两个数组上添加索引
您的名字
、姓氏
和电子邮件
字段基本上都是数组,但您应该将它们转换为嵌入式文档
"first_name": {
...
},
"last_name": {
...
},
"email": {
...
}
编辑2:
由于无法转换数据结构,您的选项减少。不能在多个数组字段上创建复合索引。为了更好地解决这个问题,您应该使用命令(可能在使用时)查看哪个索引执行得更快。我认为Christian p.给出了最好的答案。复合索引将大大帮助您的查询 <> P.>还有一件事你应该考虑,你在查询中寻找什么信息? 如果您只需要几个字段就可以减少查询的大小,那么您可以尝试使用project聚合框架
如果需要有这么多索引,请在查询中使用索引提示,以确保使用的是最好的索引。索引文档:每个查询,包括更新操作,都使用一个索引。换句话说,MongoDB不支持索引交集。因此,创建大量索引是毫无意义的,除非有查询只使用此索引和此索引。另外,请确保在此处调用了正确的Count()方法。如果您调用linq to object extensions(IEnumerable的Count()扩展而不是MongoCursor的Count,它实际上必须获取并水合所有对象)。这比Christian P要多。您关于简单相等性检查的建议听起来很有帮助。但在添加复合索引时,我得到了以下错误。如果您能提出一些解决方案,我将不胜感激。db.leads.ensureIndex({“email.email\u id”:1,“first\u name.value”:1,“last\u name.value”:1,“last\u inserted\u date”:-1});{“createdCollectionAutomatically”:false,“numIndexesBefore”:37,“ok”:0,“errmsg”:“无法为并行数组[名字][电子邮件],“code”:10088]编制索引。再次感谢您的回复。我的错是遗漏了关于结构的信息。我的要求是,我可以将字段的多个值保存为:{first_name{“0”:{},“1”:{}},last_name{“0”:{},“1”:{},email{“0”:{},“1”:{}}。可以用这种结构添加复合索引吗?提前感谢您的帮助。不幸的是,您不能在两个或多个数组上创建复合索引。