Mongodb 在运行查询之前未创建Mongoose索引

Mongodb 在运行查询之前未创建Mongoose索引,mongodb,mongoose,Mongodb,Mongoose,当运行我的测试时,我收到一个错误,说明我没有在标题字段上设置文本索引。当运行我的应用程序时,文本搜索可以在相同的模型上正常工作,并且不会抛出错误 $text查询需要文本索引(没有此类集合“test db.torrents”) 从“猫鼬”导入猫鼬; 从“./类别”导入类别; const Schema=mongoose.Schema; const Torrent=新模式({ 标题:{ 类型:字符串 }, 类别:{ 类型:mongoose.Schema.Types.ObjectId, 参考:“类别”,

当运行我的测试时,我收到一个错误,说明我没有在标题字段上设置文本索引。当运行我的应用程序时,文本搜索可以在相同的模型上正常工作,并且不会抛出错误

$text查询需要文本索引(没有此类集合“test db.torrents”)

从“猫鼬”导入猫鼬;
从“./类别”导入类别;
const Schema=mongoose.Schema;
const Torrent=新模式({
标题:{
类型:字符串
},
类别:{
类型:mongoose.Schema.Types.ObjectId,
参考:“类别”,
要求:正确,
索引:正确
},
尺寸:数量,
详情:[
{
类型:字符串
}
],
蜂群:{
播种机:数量,
李彻:号码
},
lastmod:{
类型:日期,
默认值:Date.now()
},
进口:{
类型:日期,
默认值:Date.now()
},
信息散列:{
类型:字符串,
独一无二:没错,
索引:正确
}
});
洪流指数({
标题:“文本”
}, {
背景:假
});
导出默认mongoose.model('Torrent',Torrent);
我正在使用它进行测试,这是我的测试用例

从“猫鼬”导入猫鼬;
从“supertest”导入请求;
从“ava”导入测试;
从“../helpers”导入{makeApp};
测试前(()=>{
猫鼬。承诺=承诺;
猫鼬mongodb://localhost:27017/astro-测试db');
});
测试后总是(()=>{
mongoose.connection.db.dropDatabase(()=>{
mongoose.disconnect();
});
});
//应返回[],因为HL3不存在。
test('应该不返回搜索结果',异步t=>{
const-app=makeApp();
const res=wait request(app.get)(`/api/search?q=HL3`);
t、 is(res.status,200);
t、 是(res.body.error,{});
t、 is(res.body.torrents.length,0);
});
以下是ava的完整输出,您可以看到标题索引不是使用“text”或
background:false创建的

➜  astro git:(开发)✗ 纱线ava测试/routes/search.js--verbose
纱线ava v0.24.6
$“/Users/xo/code/astro/node_modules/.bin/ava”test/routes/search.js--详细
Mongoose:categories.ensureIndex({title:1},{unique:true,background:true})
Mongoose:torrents.ensureIndex({category:1},{background:true})
Mongoose:torrents.count({},{})
Mongoose:categories.ensureIndex({slug:1},{unique:true,background:true})
Mongoose:torrents.find({'$text':{'$search':'x'},{limit:100,排序:{score:{'$meta':'textScore'},'swarm.seeders':-1},字段:{score:{'$meta':'textScore'}})
✖ 不应返回任何搜索结果
1测试失败[13:59:07]
不应返回任何搜索结果
/Users/xo/code/astro/test/routes/search.js:24
23:t.is(res.status,200);
24:t.is(res.body.error,{});
25:t.is(res.body.torrents.length,0);
区别:
-反对{
-代码:27,
-代号:“IndexNotFound”,
-errmsg:“$text查询需要文本索引(没有这样的集合'astro-test-db.torrents\”,
-消息:“文本索引需要$text查询(没有这样的集合'astro-test-db.torrents\')”,
-名称:“MongoError”,
-好:0,,
- }
+对象{}
_被叫人$(test/routes/search.js:24:7)
tryCatch(node_modules/registrator runtime/runtime.js:65:40)
Generator.invoke[as _invoke](node_modules/registrator runtime/runtime.js:303:22)
prototype.(匿名函数)[作为下一步](node_modules/registrator runtime/runtime.js:117:21)
步骤(test/routes/search.js:19:191)
错误命令失败,退出代码为1。

您应该确保索引是在“前台”中创建的,因为“后台”创建是默认的

Torrent.index({
标题:“文本”
},{“背景”:假});
至少对于您的测试,否则可能会在创建索引之前运行查询。设置
{background:false}
确保索引在其他操作运行之前存在。这与MongoDB的相反,因此它需要是一个显式设置

在生产环境中,通常最好还是通过其他方式部署索引。另外,“前台”创建会导致较小的索引大小,但当然会“阻塞”IO,但通常最好在生产中至少执行一次

引证

默认情况下,MongoDB在前台构建索引,这可以防止在构建索引时对数据库执行所有读写操作。此外,在前台索引构建期间,不会发生需要对所有数据库(例如listDatabases)进行读或写锁定的操作

这意味着发生这种情况时不会发生读取或写入。因此,在“前台”创建模式下创建索引时,无法插入数据和运行查询

至于尺寸,从引文的同一页再往下一点:

后台索引构建需要更长的时间才能完成,结果生成的索引最初比在前台构建的索引更大或更不紧凑。随着时间的推移,在后台构建的索引的紧凑性将接近前台构建的索引

因此,您可以在后台创建索引,随着时间的推移,这些索引在生产环境中的大小会变得更加紧凑。但是对于测试和开发目的,您的默认设置应该始终是在“前台”中创建,以免被时间问题所困扰


作为最低限度的测试用例:

var mongoose=require('mongoose'),
Schema=mongoose.Schema;
mongoose.set('debug',true);
var testSchema=新模式({
标题:{type:String}
});
testSchema.index({
标题:“文本”
},{背景:假});
var Test=mongoose.model('Test',testSchema);
猫鼬mongodb://localhost/texttest');
create({title:'something here'},函数(err,doc){
Test.find({“$text”){“$s