猫鼬没有为多个字段创建文本索引

时间:2019-08-10 22:31:55

标签: node.js mongodb mongoose

我有一个基本的猫鼬模式,需要我在其两个字段上创建文本索引:名称和描述。

这是我的猫鼬连接选项:

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"})

返回一个IndexOptionsConflict

{
        "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")
                }
        }
}

我只是在某个地方搞砸了吗?我当然希望如此。

1 个答案:

答案 0 :(得分:2)

在mongoDB中,您不能创建两个文本索引,即;集合的两个不同字段上的两个“单字段”文本索引。如果确实需要创建,您所能做的就是删除现有的索引(如果可以的话)并使用所有必要的文本字段创建一个新的复合索引!以下是用于Shell操作或由于您已经在架构中具有复合索引,因此可以运行代码。

做这样的事情:

db.amodels.createIndex(
   {
     name: "text",
     description: "text"
   }
 )

带砝码(可选):

db.amodels.createIndex(
    {
        name: "text",
        description: "text"
    },
    {
        weights: {
            name: 5,
            description: 3
        },
        name: "name_description"
    }
)

注意:创建索引-您可以开始使用createIndex,因为ensureIndex已过时ensureIndex to createIndex

请检查此内容以供参考:

MongoDB Text Indexes