San*_*rya 28 mongodb mongodb-query
我在mongodb创建索引,有1000万条记录但是跟着错误
db.logcollection.ensureIndex({"Module":1})
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 3,
"ok" : 0,
"errmsg" : "Btree::insert: key too large to index, failing play.logcollection.$Module_1 1100 { : \"RezGainUISystem.Net.WebException: The request was aborted: The request was canceled.\r\n at System.Net.ConnectStream.InternalWrite(Boolean async, Byte...\" }",
"code" : 17282
}
Run Code Online (Sandbox Code Playgroud)
请帮我看看如何在mongodb中创建索引,
anh*_*hlc 39
如果现有文档的索引条目超出索引键限制(1024字节),MongoDB将不会在集合上创建索引.但是,您可以创建散列索引或文本索引:
db.logcollection.createIndex({"Module":"hashed"})
Run Code Online (Sandbox Code Playgroud)
要么
db.logcollection.createIndex({"Module":"text"})
Run Code Online (Sandbox Code Playgroud)
Rus*_*m K 22
您可以使用以下命令启动mongod实例来沉默此行为:
mongod --setParameter failIndexKeyTooLong=false
Run Code Online (Sandbox Code Playgroud)
或者从mongoShell执行以下命令
db.getSiblingDB('admin').runCommand( { setParameter: 1, failIndexKeyTooLong: false } )
Run Code Online (Sandbox Code Playgroud)
如果你确保你的字段很少超过限制,那么解决这个问题的一种方法是将你的字段(导致索引超出限制)拆分为逐字节长度<1KB,例如对于字段val我会将其拆分为元组字段val_1,val_2等等.Mongo将文本存储为utf-8有效值.这意味着您需要一个可以正确拆分utf-8字符串的函数.
def split_utf8(s, n):
"""
(ord(s[k]) & 0xc0) == 0x80 - checks whether it is continuation byte (actual part of the string) or jsut header indicates how many bytes there are in multi-byte sequence
An interesting aside by the way. You can classify bytes in a UTF-8 stream as follows:
With the high bit set to 0, it's a single byte value.
With the two high bits set to 10, it's a continuation byte.
Otherwise, it's the first byte of a multi-byte sequence and the number of leading 1 bits indicates how many bytes there are in total for this sequence (110... means two bytes, 1110... means three bytes, etc).
"""
s = s.encode('utf-8')
while len(s) > n:
k = n
while (ord(s[k]) & 0xc0) == 0x80:
k -= 1
yield s[:k]
s = s[k:]
yield s
Run Code Online (Sandbox Code Playgroud)
然后你可以定义你的复合索引:
db.coll.ensureIndex({val_1: 1, val_2: 1, ...}, {background: true})
Run Code Online (Sandbox Code Playgroud)
或每个多个索引val_i:
db.coll.ensureIndex({val_1: 1}, {background: true})
db.coll.ensureIndex({val_1: 2}, {background: true})
...
db.coll.ensureIndex({val_1: i}, {background: true})
Run Code Online (Sandbox Code Playgroud)
重要提示:如果考虑在复合索引中使用您的字段,请注意
split_utf8函数的第二个参数.在每个文档中,您需要删除构成索引键的每个字段值的字节总和,例如索引(a:1,b:1,val:1)1024 - sizeof(value(a)) - sizeof(value(b))
正如不同的人在答案中指出的那样,该错误key too large to index表示您试图在长度超过1024个字节的一个或多个字段上创建索引。
用ASCII术语,通常1024个字节转换为大约1024个字符的长度。
有没有办法解决这个,因为这是在提到的MongoDB中设置一个内部限制的MongoDB限制和阈值页面:
索引条目的总大小(小于BSON类型,可能包括结构开销)必须小于1024个字节。
failIndexKeyTooLong如服务器参数手册页中所述,打开错误不是解决方案:
...这些操作将成功插入或修改文档,但一个或多个索引将不包含对该文档的引用。
该句子的意思是有问题的文档将不会包含在索引中,并且可能会从查询结果中丢失。
例如:
> db.test.insert({_id: 0, a: "abc"})
> db.test.insert({_id: 1, a: "def"})
> db.test.insert({_id: 2, a: <string more than 1024 characters long>})
> db.adminCommand( { setParameter: 1, failIndexKeyTooLong: false } )
> db.test.find()
{"_id": 0, "a": "abc"}
{"_id": 1, "a": "def"}
{"_id": 2, "a": <string more than 1024 characters long>}
Fetched 3 record(s) in 2ms
> db.test.find({a: {$ne: "abc"}})
{"_id": 1, "a": "def"}
Fetched 1 record(s) in 1ms
Run Code Online (Sandbox Code Playgroud)
通过强制MongoDB忽略该failIndexKeyTooLong错误,最后一个查询不包含有问题的文档(即_id: 2,结果中缺少的文档),因此该查询导致了错误的结果集。
小智 6
当遇到“索引键限制”时,解决方案取决于您的架构的需求。在极少数情况下,设计要求对大于 1024 字节的值进行密钥匹配。事实上,几乎所有数据库都施加了索引键限制,但通常在传统关系数据库(Oracle/MySQL/PostgreSQL)中可以进行一定程度的配置,因此您很容易搬起石头砸自己的脚。
为了快速搜索,“文本”索引旨在优化长文本字段的搜索和模式匹配,并且非常适合该用例。然而,更常见的是,需要对长文本值进行唯一性约束。并且“文本”索引的行为与具有唯一标志集的唯一标量值不同
{ unique: true }(更像是字段中所有文本字符串的数组)。
受到 MongoDb 的 GridFS 的启发,通过向文档添加“md5”字段并在其上创建唯一的标量索引,可以轻松实现唯一性检查。有点像自定义的唯一哈希索引。这允许几乎无限的(〜16mb)文本字段长度,该长度被索引以供搜索并且在整个集合中是唯一的。
const md5 = require('md5');
const mongoose = require('mongoose');
let Schema = new mongoose.Schema({
text: {
type: String,
required: true,
trim: true,
set: function(v) {
this.md5 = md5(v);
return v;
}
},
md5: {
type: String,
required: true,
trim: true
}
});
Schema.index({ md5: 1 }, { unique: true });
Schema.index({ text: "text" }, { background: true });
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
32226 次 |
| 最近记录: |