我有一个名为Post的系列。我有一个映射系统,始终确保每个文档都包含以下字段:
访问此集合以在API架构中输出。
所以一些典型的请求可能是:
/post?type=image&user_id=2
/post?updated=35234423&order_by=client_id
/post?enabled=true&order_by=id
没有100%保证某些字段可以进入查找或排序字段。
最近,当表格达到8GB时,我开始收到此错误:
"localhost:27017: too much data for sort() with no index. add an index or specify a smaller limit"
我查看了Mongo索引的文档,发现很难理解它是否与MySQL索引的工作方式相同。
我在索引时找到的一些线程:MongoDB - too much data for sort() with no index error似乎建议使用特定的排序字段来确保索引被命中。很明显,当我的过滤和排序很多是可选的时,我不能这样做。
对于我是否应该索引我桌上的所有字段,有人可以建议一个坚定的解决方案吗?
感谢您的反馈,我已经开始构建自动索引功能:
public function get() {
$indices['Post'] = array(
'fields' =>
array(
'id' => array('unique' => true, 'dropDups' => true, 'background' => true),
'client_id' => array('dropDups' => true, 'background' => true),
'image_id' => array('dropDups' => true, 'background' => true),
'user_id' => array('dropDups' => true, 'background' => true),
'publish_target' => array('dropDups' => true, 'background' => true),
'type' => array('dropDups' => true, 'background' => true),
'status' => array('dropDups' => true, 'background' => true),
'text' => array('background' => true)
)
);
foreach ($indices as $key => $index) {
/* set the collection */
$collection = $this->mongoDB->{$key};
/* delete the indexes */
$collection->deleteIndexes();
/* loop the fields and add the index */
foreach ($index['fields'] as $subKey => $data) {
$collection->ensureIndex($subKey, array_merge($data, array('name' => $subKey)));
}
}
/* return the list */
return $indices;
}
答案 0 :(得分:2)
您应该事先了解哪种查询会进入服务器。如果没有它,你就无法进行任何优化,并且可能遇到像现在这样的排序问题。
如果您说用户可以按照您拥有的9个字段中的任何一个进行排序,则需要在每个字段上创建索引。但是,您需要记住,有时创建复合索引更有意义,因为防止了以下问题:
/post?updated=35234423&order_by=client_id
只能通过设置索引来完成:
{ updated: 1, client_id: 1 }
只有当索引中的所有左侧字段都是您查询的一部分时,才能使用MongoDB中的索引。
所以:{ updated: 1, client_id: 1 }
最适合:
find( { 'updated' : 1 } );
find( { 'updated' : 1, 'client_id' : 1 } );
find( { 'updated' : 1 } ).sort( { 'client_id' : 1 } );
但不是为了:
find( { 'client_id' : 1 } );
find( { 'client_id' : 1 } ).sort( { 'updated' : 1 } );
为了减少数据量并防止出现错误消息,您还可以为每个查询添加limit()
。有了8MB的结果,我怀疑你的UI无论如何都可以显示很多结果,所以使用limit()
可能有意义。
答案 1 :(得分:1)
不幸的是,我想不出一个非常好的解决方案来解决索引的动态性,但是这个JIRA https://jira.mongodb.org/browse/SERVER-3071会对你有所帮助。
我建议您观看JIRA门票。