I'm getting an empty array when using $search
in mongoose.
Schema
const mongoose = require('mongoose');
const studentSchema = new mongoose.Schema({
name: { type: String },
});
studentSchema.index({ name: 'text' });
const Student = mongoose.model('Student', studentSchema);
module.exports = Student;
$search
const Student = require('../models/Student.Model');
(async () => {
const result = await Student.aggregate([
{
$search: {
index: 'default',
compound: {
must: [
{
text: {
query: 'Lee',
path: 'name',
fuzzy: {
maxEdits: 1,
},
},
},
],
},
},
},
]);
})();
This gives me an empty array. So I tried another syntax.
const result = await Student.aggregate().search({
index: 'default',
compound: {
must: [
{
text: {
query: 'Lee',
path: 'name',
fuzzy: {
maxEdits: 1,
},
},
},
],
},
});
That also gave me an empty array.
To test whether the model was working I used find
and filter
, and could see similar results I'd expect to see with $search
.
let result2 = await Student.find({});
result2 = result2.filter((p) => p.name.includes('Lee'));
result2
had two documents
result2: [
{ _id: 625f70ac90e916620045cab5, name: 'Brian Lee', __v: 0 },
{ _id: 625f70e39660b486c82b2011, name: 'Lee Cohen', __v: 0 }
]
Update: find
and $text
also give me the above correct results, but I want to implement a fuzzy search and I don't think you can with find
and $text`:
const resultsShort = await Student.find({ $text: { $search: 'Lee' } });
Why isn't $search
returning these two documents?
CodePudding user response:
This creates a $text index not an Atlas Search index:
studentSchema.index({ name: 'text' });
The above can be removed.
You can't create an Atlas Search index on a mongoose schema, it has to be set on the Atlas site or the CLI.
To create an Atlas Search index, go to your database on cloud.mongodb.com ->Search-->Create Search Index-->JSON Editor-->Next-->pick your collection--> set the index name. here it would be 'default'
Then set the index:
{
"mappings": {
"dynamic":false,
"fields":{
"name":{
"analyzer":"lucene.standard",
"type":"string"
}
}
}
Then this code works.
const result = await Student.aggregate().search({
index: 'default',
compound: {
must: [
{
text: {
query: 'Lee',
path: 'name',
fuzzy: {
maxEdits: 1,
},
},
},
],
},
});
```
CodePudding user response:
Use $regex
db.collection.find({
name: {
$regex: "Lee"
}
})
createIndex
db.collection.createIndex({name:"text"})
text search
db.collection.find({$text: {$search: "Lee"}})