用mongoosesorting阿尔法

我试图通过mongoose3.6.20sorting,我收到了一些意想不到的结果。

我有一个名字的公司名单。 起初我以为也许它是在区分大小写的方式。 基于文章,我期望是真实的。

我现在正在使用虚拟属性来排除sorting字段。 不过,我仍然得到意想不到的结果。

CompanySchema.virtual('name_lower').get(function(){ return this.name.toLowerCase(); }); 

当我sorting

 Company.find().sort({ name_lower: 1 }); 

我按照以下顺序得到它:

  1. 公司名
  2. 谷歌
  3. 公司名称(是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,所以有两个选项:

  1. 正如你所说,创build一个新的字段的名称sanitized全部小写
  2. 对所有数据运行一个大循环,并将每个公司名称更新为小写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(); });