【问题标题】:sorting alpha with mongoose用猫鼬对 alpha 进行排序
【发布时间】:2013-10-26 11:11:06
【问题描述】:

我正在尝试通过 mongoose 3.6.20 进行排序,但收到了一些意想不到的结果。

我有一个有名字的公司列表。起初我以为它可能是以区分大小写的方式排序。根据文章,我认为这是真的。

我现在使用虚拟属性来降低排序字段的大小写。但是,我仍然得到了意想不到的结果。

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

当我排序时

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

我按以下顺序获取它:

  1. 公司名称
  2. 谷歌
  3. 公司名称(是的,重复测试)

我也在输出我的虚拟财产的价值,它看起来是正确的。没有空格或时髦的字符会导致第二个“公司名称”出现在 google 之后。

使用 nodejs、express、mongoose。

我遗漏了什么或做错了什么?


更新:

根据答案中提供的信息,我重构了我的架构以包含一些规范化字段并连接到我的文档的预保存事件中,在此我更新这些规范化字段并在以后的所有查询中使用它们进行排序。

CompanySchema.pre('save', function(next){
  this.normalized_name = this.name;
});

接下来,在我使用的架构中:

var CompanySchema = mongoose.Schema({
  ...
  normalized_name: { type: String, set: normalize },
  ...
});

其中normalize 是一个函数,它现在返回传递给它的值的小写版本。但是,这使我可以在以后非常快速地对其进行扩展,并且我可以快速对可能需要排序的其他字段进行相同的操作。

【问题讨论】:

  • 您不能对虚拟属性进行排序。
  • 好的。很高兴知道。我正在尝试做的事情有替代解决方案吗?还是我必须将名称存储在不同的字段中,但在将其保存到文档之前将其小写?
  • 你能写出你的解决方案作为答案吗? @user2787799

标签: node.js mongodb express mongoose


【解决方案1】:

从 MongoDB v3.4 开始,可以使用collation 方法进行不区分大小写的排序:

Company.find()
    .collation({locale: "en" }) //or whatever collation you want
    .sort({name:'asc'})
    .exec(function(err, results) {
        // use your case insensitive sorted results
    });

【讨论】:

    【解决方案2】:

    很遗憾 MongoDB 和 Mongoose 目前不支持复杂排序,所以有两种选择:

    1. 如您所说,创建一个新字段,并将名称清理为全部小写
    2. 对所有数据运行一个大的for 循环并将每个公司名称更新为小写形式:

      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()
    

    请参阅Update MongoDB collection using $toLowerMongoose: Sort alphabetically 了解更多信息。

    【讨论】:

      【解决方案3】:

      我想把它放在这个钩子里:

      CompanySchema.pre('save', function(next){
        this.normalized_name = this.name;
      });
      

      如果您想将normalized_name 保存在数据库中,您必须在最后调用next();,因此预保存挂钩如下所示:

      CompanySchema.pre('save', function(next){
        this.normalized_name = this.name;
        next();
      });
      

      【讨论】:

        【解决方案4】:

        这个答案似乎对我更有帮助。我必须考虑变音符号以及案例,所以我使用了strength:3

        Mongoose: Sort alphabetically

        【讨论】:

          猜你喜欢
          • 2022-01-20
          • 2016-05-03
          • 2020-12-18
          • 2014-03-10
          • 2019-06-19
          • 2019-09-16
          • 2023-03-08
          • 1970-01-01
          • 2020-08-10
          相关资源
          最近更新 更多