Node.js Mongoose不为多个字段创建文本索引

Node.js Mongoose不为多个字段创建文本索引,node.js,mongodb,mongoose,Node.js,Mongodb,Mongoose,我有一个基本的mongoose模式,它要求我在两个字段上创建一个文本索引:name和description 以下是我的猫鼬连接选项: mongoose.set('useFindAndModify', false); mongoose.set('useCreateIndex', true); mongoose.set('useNewUrlParser', true); const mongoOptions = { useNewUrlParser: true, autoIndex: fal

我有一个基本的mongoose模式,它要求我在两个字段上创建一个文本索引:name和description

以下是我的猫鼬连接选项:

mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndex', true);
mongoose.set('useNewUrlParser', true);

const mongoOptions = {
  useNewUrlParser: true,
  autoIndex: false,
  reconnectTries: Number.MAX_VALUE,
  reconnectInterval: 500,
  poolSize: 10,
  bufferMaxEntries: 0
};

mongoose.connect(MONGOURI, mongoOptions);
这是我的模式:

const ASchema = new mongoose.Schema({
  name: {type: String, text: true, index: true, required: true, maxlength: [100, 'Name must be less than 100 characters']},
  description: {type: String, text: true, index: true, required: true, maxlength: [500, 'Description must be less than 500 characters']},
  meta: {tags: [String]}
});

ASchema.options.autoIndex = true;

ASchema.index({
  name: 'text',
  description: 'text',
}, {
  weights: {
    name: 5,
    description: 3,
  },
});

var A = mongoose.model("AModel", ASchema);

module.exports = A;
出于查询的某些原因,我使用以下方法创建:

app.post('/search', (req, res, next) => {
  let query = req.query.q
  console.log(query);
  A.find({
    $text: { $search: query }
  }, { score: { $meta: "textScore" } }
  ).sort( { score: { $meta: "textScore" } } )
  .then(q => {
    console.log(q); res.send(q)
  })
  .catch(next)
});
只有当我的查询字符串在name字段中时,我才会得到结果。 然而,当我只在描述中输入一个句子或单词时,返回的是一个空数组

在我的mongo shell上调用db.amodels.getIndexes(),将返回以下结果:

[
        {
                "v" : 2,
                "key" : {
                        "_id" : 1
                },
                "name" : "_id_",
                "ns" : "adatabase.amodels"
        },
        {
                "v" : 2,
                "key" : {
                        "_fts" : "text",
                        "_ftsx" : 1
                },
                "name" : "name_text",
                "ns" : "adatabase.amodels",
                "background" : true,
                "weights" : {
                        "name" : 1
                },
                "default_language" : "english",
                "language_override" : "language",
                "textIndexVersion" : 3
        }
]
我可以从这一点以及我的mlab实例中看出,我的复合索引尚未创建,也没有分配适当的权重

调用db.amodels.ensureIndex({“description”:“text”})

返回一个
索引选项冲突

{
        "operationTime" : Timestamp(1565476058, 1),
        "ok" : 0,
        "errmsg" : "Index: { v: 2, key: { _fts: \"text\", _ftsx: 1 }, name: \"description_text\", ns: \"adatabase.amodels\", weights: { description: 1 }, default_language: \"english\", language_override: \"language\", textIndexVersion: 3 } already exists with different options: { v: 2, key: { _fts: \"text\", _ftsx: 1 }, name: \"name_text\", ns: \"adatabase.amodels\", background: true, weights: { name: 1 }, default_language: \"english\", language_override: \"language\", textIndexVersion: 3 }",
        "code" : 85,
        "codeName" : "IndexOptionsConflict",
        "$clusterTime" : {
                "clusterTime" : Timestamp(1565476058, 1),
                "signature" : {
                        "hash" : BinData(0,"FMoSr4UQZWqocfrRTFvGoa62TsY="),
                        "keyId" : NumberLong("6723301754588364801")
                }
        }
}

我是不是把某个地方搞砸了?我当然希望如此。

在mongoDB中,您不能创建两个文本索引,即;集合的两个不同字段上的两个单字段文本索引。如果真的需要创建,您所能做的就是删除现有的索引(如果可以的话)&创建一个包含所有必要文本字段的新复合索引!!下面是shell操作,或者由于模式中已经有了复合索引,所以可以运行代码

这样做:

db.amodels.createIndex(
   {
     name: "text",
     description: "text"
   }
 )
带重量(可选):

注意:Regd。您创建的索引-您可以开始使用
createIndex
,因为
ensureIndex
已被弃用

请勾选此项以供参考:


谢谢!现在效果很好。有没有办法实现直接在代码中创建这个复合索引,而不是每次都使用shell?编辑:我还注意到我在模式文件中的权重没有得到实现?@Bdyce:您在模式中正确创建了复合索引,唯一的问题是mongoDB已经有了文本索引,您不能像这样更改现有索引,您需要删除它。我不完全确定mongoose dropIndex,然后使用代码创建它!!权重有什么问题?删除数据库中的所有集合后。我重新连接,这将运行我的mongoose代码,其中应在实例上创建复合索引。相反,只在“name”字段上创建单个文本索引<代码>{“v”:2,“键”:{“fts”:“文本”,“ftsx”:1},“名称”:“名称”;“文本”,“ns”:“adatabase.amodels”,“背景”:真,“权重”:{“名称”:1},“默认语言”:“英语”,“语言”覆盖::“语言”,“文本索引版本”:3}正如您在这里看到的,我在模式文件中包含的权重没有放在索引中。删除这个“名称”索引后,我必须在shell中运行
db.amodels.createIndex({name:,description:“text”})
,以便创建复合索引。这个索引上的权重也是简单的{“name”:1,“description”:1},这不是我的架构文件中的权重?感谢所有的帮助,问题似乎不是
autoIndex:true
而是我字段上的
index:true
text:true
选项。干杯问题解决了!
db.amodels.createIndex(
    {
        name: "text",
        description: "text"
    },
    {
        weights: {
            name: 5,
            description: 3
        },
        name: "name_description"
    }
)