mongoose text search not returning results - node.js

I am trying to create a simple text search on a combined index.
Here is my mongoose model:
// models/user.js
// load the things we need
var mongoose = require('mongoose');
// define the schema for our user model
var itemSchema = mongoose.Schema({
globalinfo : {
ownerobjectid : String,
name : String,
desc : String,
startdate : Date,
enddate : Date,
price : Number,
status : String,
statuscss : String,
dateadded : Date,
locationline1 : String,
locationline2 : String,
locationline3 : String,
locationtown : String,
locationpostcode : String,
locationlatitude : Number,
locationlongitude : Number,
termsapprove : Boolean,
friendlyurl : String,
itemsearchinfo : String,
}
});
itemSchema.index(
{
"globalinfo.itemsearchinfo": "text",
"globalinfo.name": "text"
}
); // schema level
// create the model for users and expose it to our app
module.exports = mongoose.model('Item', itemSchema);
This is my search query:
Item.find(
{ $text : { $search : "item" } }
).exec(function(err, items) {
The issue is that the query always returns no results!
I have one document in the model:
{
"_id" : ObjectId("56781cb97ae92ff08b55d4f1"),
"globalinfo" : {
"friendlyurl" : "item-a",
"dateadded" : ISODate("2015-12-21T15:37:29.591Z"),
"itemsearchinfo" : "Woop lawn mower for rent!\nYou should use this space to describe the item in detail and make it appealing\nTo the renter write your stuff here.",
"statuscss" : "na",
"status" : "Not Available Yet",
"locationlongitude" : null,
"locationlatitude" : null,
"locationpostcode" : "test",
"locationtown" : "test",
"locationline3" : "",
"locationline2" : "",
"locationline1" : "test",
"termsapprove" : true,
"price" : 3,
"enddate" : ISODate("2015-12-31T00:00:00.000Z"),
"startdate" : ISODate("2015-12-23T00:00:00.000Z"),
"desc" : "\n <h3>woop Lawn Mower for Rent! </h3>\n <p>You should use this space to describe the item in detail and make it appealing to the renter <strong>Write your stuff here.</strong> \n </p>",
"name" : "item A",
"ownerobjectid" : "56781909155232b7871edb17"
},
"__v" : 0
}
The output of db.items.getIndexes():
[
{
"v" : 1,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "whatplot_local_db.items"
},
{
"v" : 1,
"key" : {
"_fts" : "text",
"_ftsx" : 1
},
"name" : "itemsearchinfo_text_name_text",
"ns" : "whatplot_local_db.items",
"background" : true,
"weights" : {
"itemsearchinfo" : 1,
"name" : 1
},
"default_language" : "english",
"language_override" : "language",
"textIndexVersion" : 2
}
]

Have you tried re-indexing the collection?
Mongo command:
db.collection.reIndex();
The issue was with the way I was indexing. Using double quotes does not work:
itemSchema.index(
{
"globalinfo.itemsearchinfo": "text",
"globalinfo.name": "text"
}
); // schema level
However single quotes does:
itemSchema.index(
{
'globalinfo.itemsearchinfo': "text",
'globalinfo.name': "text"
}
); // schema level

Related

Appending to list works in MongoDB shell, but not in Node,js

This is the structure of the file.
{
"_id" : ObjectId("5f45274bbbe768fe0d56d9d0"),
"article" : "article-name",
"comments" : [
{
"id" : "_lj7cfhx7z",
"name" : "person",
"date" : "25/08/2020",
"text" : "asdasdsddsdsdasd",
"replies" : [
{
"name" : "person2",
"date" : "25/08/2020",
"text" : "replyyyteextttttt"
},
{
"name" : "person3",
"date" : "25/08/2020",
"text" : "replyyyteextttttt"
}
]
},
{
"id" : "_wpdpj7kv6",
"name" : "person4",
"date" : "25/08/2020",
"text" : "aaaa",
"replies" : [ ]
}
]
}
I am trying to write a function that appends to replies list given the id of the comment. When I do it in the MongoDB shell like this db.comments.findOneAndUpdate({"article": "exif-parsing", "comments.id": "_t2aqbhi5a"}, {"$push": {"comments.$.replies": {"text": "new"}}});, it works. But in Node.js it doesn't work.
var db = new DataBase("mongodb://localhost:27017/")
replyTo(article, id, name, comment) {
db.connect("blog", "comments", function(collection) {
var reply = {name: name, date: getCurrentDate(), text: comment};
collection.findOneAndUpdate({"article": article, "comments.id": id}, {"$push": {"comments.$.replies": reply}});
});
}

How to sort my users by field in an array ? mongoose

i have this model user
Model : users
u_email: String,
u_password: String,
u_displayed:Boolean,
u_info:[
{
pi_id:{type: Schema.Types.ObjectId, ref: 'wt_infos'},
key:String,
value:String,
}],
Example
"u_info" : [
{
"value" : "200",
"key" : "budget",
"pi_id" : ObjectId("5adf5bb8c7091c39300223cd")
},
{
"value" : "23/02/2019",
"key" : "date",
"pi_id" : ObjectId("5adf5bb8c7091c39300223cf")
},
How to sort my users, by my field "budget" that should be converted to int and have this id 5adf5bb8c7091c39300223cd using aggregate

Inserting a document in mongoose with empty sub document(Array), creates empty document?

const mongoose = require('mongoose');
const orgSchema = new mongoose.Schema({
org_name : {
type : String,
required : true
},
admin : {
type : String,
required : true
},
branches : [{
branch_name : {
type : String,
required :true
},
branch_admin : {
type : String,
required : true
},
branch_locations : [{
_id : false,
sub_branch_name : {
type : String
},
sub_branch_admin : {
type : String
}
}]
}],
plan : {
type : mongoose.Schema.Types.ObjectId,
ref : 'plan',
required : true
},
status : {
type : String,
enum : ['ACTIVE', 'EXPIRED']
}
});
orgSchema.createIndex = ({
org_name : 1
},{
unique : true
});
module.exports = mongoose.model('organizations', orgSchema);
//Above is schema
{
"_id" : ObjectId("5bf91a1edc7ed22ca90d4624"),
"org_name" : "xxxxxxxxxxxxxxx",
"admin" : "sssssss",
"branches" : [
{
"_id" : ObjectId("5bf91a1edc7ed22ca90d4625"),
"branch_name" : "ssssss",
"branch_admin" : "ddd",
"branch_locations" : [
{}//automatically creates empty doc when no fields
]
}
],
"plan" : ObjectId("5bf91a1edc7ed22ca90d4623"),
"status" : "ACTIVE",
"__v" : 0
}
when i try to insert a document with empty fields in the sub document array, it returns with {} in array of sub document.
How to get rid from the new empty document in sub document. I should get an empty array when there is no field in the sub document to save...

How to perform a part of text search in mongoose array of objects

I have a schema where I need to perform a search in array of objects. I have tried many ways but it doesn't seems to work. Below is my code.
let productsSchema = new mongooseSchema({
productId: {type: mongooseSchema.Types.ObjectId, ref: 'Product'},
mainAttributes: [{
subCategoryId: {type: mongooseSchema.Types.ObjectId, ref: 'CategorySubCategory'},
attributes: Object
}],
createdAt: Date,
updatedAt: Date
})
productsSchema.index({'mainAttributes': 'text'})
let attributes = mongoose.model('Attributes', productsSchema);
let results = await CategorySubCategory.attributes.find({"$text": {"$search": req.body.searchText}})
Currently below record is saved in mongodb
{
"_id" : ObjectId("5bba1b39ad9387431f9f5fd9"),
"productId" : ObjectId("5bba1b397d90713320c441f8"),
"__v" : 0,
"createdAt" : ISODate("2018-10-07T14:42:01.723Z"),
"mainAttributes" : [
{
"_id" : ObjectId("5bba1b397d90713320c441f9"),
"subCategoryId" : ObjectId("5bba1b397d90713320c441f7"),
"attributes" : {
"title" : {
"text" : "some title",
"type" : "text"
}
"state" : {
"text" : "California",
"type" : "text"
},
"city" : {
"text" : "San Francisco",
"type" : "text"
}
}
},
{
"_id" : ObjectId("5bba1b397d90713320c441fb"),
"subCategoryId" : ObjectId("5bba1b397d90713320c441fa"),
"attributes" : {
"temprature" : {
"degree" : "20C",
"type" : "text"
}
}
}
],
"updatedAt" : ISODate("2018-10-07T14:42:01.723Z")
}
I need to perform a search on the basis of text, e.g. when I give San, it should return me the result, but it returns empty.
I have figured it out what was the problem,
I need to explicitly remove an index, and then added
productsSchema.index({'$**': 'text'}) to make it work

Mongoose, Find Model property

I'm using express and mongoose to retrieve data from mongodb, when i try to query:
Event.find({"StartTime":{$gte:start, $lte: end }}, function(err, today){
cb({"all":docs, "live_total": docs.length, "today":today, "today_total": today.length, "start":start, "end":end, "now":now});
})
It returns results, but when i do:
Event.find({"League":"2399913"}, function(err, ev){
console.log(ev)
})
It returns nothing even if i do manually the query in mongodb return results:
query on mongo
db.events.find({"League": "50012238"});
results
{ "_id" : ObjectId("58c02fc1a683a6595444b5d0"), "EventID" : "62332340", "League" : "50012238", "LeagueName" : "King's Cup", "Sport" : "6046", "SportName" : "Football", "Location" : "80", "LocationName" : "Saudi Arabia", "StartTime" : ISODate("2017-01-21T07:15:00Z"), "homeTeam" : "50038781", "homeTeamName" : "Al Safa (KSA)", "awayTeam" : "250417", "awayTeamName" : "Al Qadisiya", "EventStatus" : "NSY", "Active" : "I", "BookmakerTotalCnt" : "3", "Outcomes" : { "Outcome" : { "OutcomeID" : "1", "OutcomeName" : "1X2", "Bookmaker" : { "BookmakerID" : "8", "BookmakerName" : "Bet365", "BookmakerTotalOddsCnt" : "18", "Odd" : [ { "EventID" : "62332340", "LineID" : "586978", "OutcomeID" : "1", "BookmakerID" : "8", "OutcomeName" : "1X2", "BookmakerName" : "Bet365", "bet" : "1", "BaseLine" : null, "line" : null, "CurrentPrice" : "6", "isResulting" : "-", "isWinner" : "0", "OutcomeType" : "1", "DrawName" : "X", "LineInfo" : null, "LineStatus" : "Open" }, { "EventID" : "62332340", "LineID" : "586979", "OutcomeID" : "1", "BookmakerID" : "8", "OutcomeName" : "1X2", "BookmakerName" : "Bet365", "bet" : "2", "BaseLine" : null, "line" : null, "CurrentPrice" : "1.4", "isResulting" : "-", "isWinner" : "0", "OutcomeType" : "1", "DrawName" : "X", "LineInfo" : null, "LineStatus" : "Open" }, { "EventID" : "62332340", "LineID" : "586980", "OutcomeID" : "1", "BookmakerID" : "8", "OutcomeName" : "1X2", "BookmakerName" : "Bet365", "bet" : "X", "BaseLine" : null, "line" : null, "CurrentPrice" : "4.333", "isResulting" : "-", "isWinner" : "0", "OutcomeType" : "1", "DrawName" : "X", "LineInfo" : null, "LineStatus" : "Open" } ] } } } }
Here is my model definition:
var mongoose = require('mongoose');
var model = {};
//static method
exports.schema = function(req, res){
return mongoose.Schema({
Sport: Number,
League: Number,
LeagueName: String,
Location: String,
SportName: String,
StartTime: Date,
StartTimeJS: Date,
LocationName: String,
homeTeam: String,
homeTeamName: String,
awayTeam: String,
awayTeamName: String,
EventStatus: String,
Active: Number,
BookmakerTotalCnt: String,
Outcomes: Array,
EventID: Number
});
}
So basically it finds by some keys but not for others, any idea?
Manually you did right query:
db.events.find({"League": "50012238"});
But in this query "U" into "Lueague" is wrong!
Event.find({"Lueague":"2399913"}, function(err, ev){
console.log(ev)
})
Try this:
Event.find({"League": 2399913}).exec(function(err, ev)
{ console.log(ev) });
The issue is probably that you're telling Mongoose that League is a number, yet it seems to be stored in the database as a string.
Because of this, Mongoose runs the equivalent of this query (because Mongoose will cast the string "2399913" in the query to a number, so it matches the schema type):
db.events.find({ League : 2399913 })
Notice how there are no quotes around the number.
Because strings and numbers are different things, this query won't match any of the documents in your collection.
The fix would be to update your schema so League becomes a string:
League: String,

Resources