用mongoosesorting阿尔法
我试图通过mongoose3.6.20sorting,我收到了一些意想不到的结果。
我有一个名字的公司名单。 起初我以为也许它是在区分大小写的方式。 基于文章,我期望是真实的。
我现在正在使用虚拟属性来排除sorting字段。 不过,我仍然得到意想不到的结果。
CompanySchema.virtual('name_lower').get(function(){ return this.name.toLowerCase(); });
当我sorting
Company.find().sort({ name_lower: 1 });
我按照以下顺序得到它:
- 公司名
- 谷歌
- 公司名称(是testing重复)
我也输出我的虚拟财产的价值,它看起来是正确的。 没有可能导致第二个“公司名称”出现在Google之后的空白字符或时髦字符。
使用nodejs,express,mongoose。
我错过了什么或做错了什么?
更新:
根据答案中提供的信息,我重构了我的模式以包含一些规范化字段,并将其挂接到文档的预保存事件中,在那里我更新这些规范化字段并在将来的所有查询中使用它们进行sorting。
CompanySchema.pre('save', function(next){ this.normalized_name = this.name; });
接下来,在我使用的模式中:
var CompanySchema = mongoose.Schema({ ... normalized_name: { type: String, set: normalize }, ... });
凡normalize
是一个函数,现在,返回一个小写的值传递给它的值。 但是,这使得我可以很快地扩展它,并且可以快速地对其他可能需要sorting的领域进行相同的处理。
不幸的是,MongoDB和Mongoose目前不支持复杂的sorting,所以有两个选项:
- 正如你所说,创build一个新的字段的名称sanitized全部小写
-
对所有数据运行一个大循环,并将每个公司名称更新为小写forms:
db.CompanyCollection.find().forEach( function(e) { e.CompanyName = e.CompanyName.toLowerCase(); db.CompanyCollection.save(e); } )
要么
db.CompanyCollection.update({_id: e._id}, {$set: {CompanyName: e.CompanyName.toLowerCase()
请参阅使用$ toLower和Mongoose 更新MongoDB集合 :按字母顺序sorting以获取更多信息。
从MongoDB v3.4开始,可以使用整理方法进行不区分大小写的sorting:
Company.find() .collation({locale: "en" }) //or whatever collation you want .sort({name:'asc'}) .exec(function(err, results) { // use your case insensitive sorted results });
我想在这个钩子里说出来:
CompanySchema.pre('save', function(next){ this.normalized_name = this.name; });
你必须调用next();
最后,如果要将normalized_name
保存在数据库中,则预保存钩子将如下所示:
CompanySchema.pre('save', function(next){ this.normalized_name = this.name; next(); });