【问题标题】:Mongoose text search not returning any results猫鼬文本搜索不返回任何结果
【发布时间】:2020-03-16 19:58:58
【问题描述】:

我正在为我的应用程序使用 Mongoose 5.7.8,但文本搜索未返回任何结果。

这是一个架构/模型:

import mongoose, { Document, Schema } from 'mongoose';
import { Moment } from 'moment';
import { IUser } from './IUser.model';
import mongooseMoment from 'mongoose-moment';

mongooseMoment(mongoose);

export interface IProfile extends Document {
  given_name: string;
  family_name: string;
  nickname: string;
  name?: string;
  picture?: string;
  locale?: string;
  updated_at?: Moment;
  email?: string;
  email_verified?: string;
  sub: string;
  user: IUser['_id'];

  bySub(sub: string): any;
}

export const ProfileSchema: Schema = new Schema({
  given_name: {type: Schema.Types.String, required: true},
  family_name: {type: Schema.Types.String, required: true},
  nickname: {type: Schema.Types.String, required: true},
  name: {type: Schema.Types.String, required: false, unique: false},
  picture: {type: Schema.Types.String, required: false, unique: false},
  locale: {type: Schema.Types.String, required: false, unique: false},
  updated_at: {type: 'Moment', required: false, unique: false},
  email: {type: Schema.Types.String, required: false, unique: false},
  email_verified: {type: Schema.Types.String, required: false, unique: false},
  sub: {type: Schema.Types.String, required: true, unique: true, index: true},
  user: {type: Schema.Types.ObjectId, ref: 'User'}
});

ProfileSchema.query.bySub = function (sub: string) {
  return this.where({sub});
};

ProfileSchema.index({'given_name': 'text', 'family_name': 'text', 'nickname': 'text'});

export default mongoose.model<IProfile>('Profile', ProfileSchema);

这是一个正在搜索配置文件的控制器:

const criteria = 'a';

const profiles: IProfile[] = await Profile.find(
  {
    $text:
      {
        $search: criteria,
      }
  }
);

不幸的是,profiles 始终为空,即使存在符合条件的文档。我可能做错了什么?

【问题讨论】:

    标签: javascript node.js mongodb typescript mongoose


    【解决方案1】:

    创建索引似乎存在一些一致性问题。您可能会在创建索引之前触发查询,甚至可能还没有创建索引。以下内容在测试时适用于本地开发。

    我建议您直接在 Mongodb 中创建索引,并在连接字符串中完全使用 autoIndex: false 从 Moongose 中删除索引创建。

    mongoose.connect(`mongodb://localhost/tests`, {useNewUrlParser: true, useUnifiedTopology: true, autoIndex: false});
    

    但对于开发人员并帮助回答您的问题:

    定义索引,然后运行await Profile.ensureIndexes(); 检查模型的索引是否存在。如果需要,它将运行 createIndex

    查看 cmets 内联:

    // define schema
    let schema = new Schema(
        {
            id: {
                type: Number,
                required: true
            },
            name: {
                type: String,
                required: true
            },
            content: {
                type: String,
                required: true
            }
        },
        {
            versionKey: false,
            timestamps: false,
            autoIndex: false // set false as this create significant load on your production database
        }
    );
    
    // define the text index
    schema.index({ content: 'text', name: 'text' }, {name: 'my text index'});
    
    // initialize the model
    const Profile = mongoose.model('profiles', schema);
    
    // insert some data
    const profile = await Profile.create({
        id: 1,
        name: 'Darth "The Sith Lord" Vader',
        content: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
    });
    
    // event to notify us when indexes are created
    Profile.on('index', (err) => {
        if (err) {
            return console.error(err);
        }
    
        console.info(`index created`);
    });
    
    // ensure we have the indexes, this will use createIndex in the background
    await Profile.ensureIndexes();
    
    // now run the query using the index
    const result = await Profile.find({
            $text:
                {
                    $search: 'consectetur adipiscing',
                }
        },
        {
            _id: 0,
            name: 1
        }
    );
    
    console.info(result);
    [ { name: 'Darth "The Sith Lord" Vader' } ]
    

    【讨论】:

    • 当我将索引直接添加到 MongoDB 时它可以工作。谢谢!
    猜你喜欢
    • 2016-03-27
    • 1970-01-01
    • 1970-01-01
    • 2014-05-30
    • 1970-01-01
    • 2015-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多