Error: text search not enabled:- in mongodb - node.js

I get the following error :-
[Error: text search not enabled]
I am running the folliowing function which is essentially a mongoose-mongodb operation.
var textSearch = require('mongoose-text-search');
exports.dbTextSearch = function () {
console.log('dbTextSearch');
var gameSchema = mongoose.Schema({
name: String
, tags: [String]
, likes: Number
, created: Date
});
gameSchema.plugin(textSearch);
gameSchema.index({ tags: 'text' });
var Game = mongoose.model('Game', gameSchema);
Game.create({ name: 'Super Mario 64', tags: ['nintendo', 'mario', '3d'] }, function (err) {
Game.textSearch('3d', function (err, output) {
if (err) return console.log(err); // this outputs the error.
var inspect = require('util').inspect;
console.log(inspect(output, { depth: null }));
});
});
}
I am trying to implement the mongoose-text-search plugin

In MongoDB 2.4 - to enable the experimental text search, use
setParameter=textSearchEnabled=true
The following line didn't work for me in the mongodb.conf file.
textSearchEnabled=true
EDIT In MongoDB 2.6 + it is enabled by default. You just need to set up your text indexes.

MongoDB Text search is still an experimental feature. That's why it is disabled by default and must be enabled manually. You can do so by either starting mongod with the command line parameter --setParameter textSearchEnabled=true or adding the line textSearchEnabled=true to the file mongodb.conf.
Please note that as an experimental feature, text search should not be used in a production environment yet.
UPDATE
As of version 2.6 of mongoDB text search feature has production-quality and is enabled automatically.

You have to specify this startup parameter (mentioned in above answers) when you start mongo. So if you start manually, then use:
mongod --setParameter textSearchEnabled=true
Otherwise, if mongo is deamonized, put it into deamon script. Something like this:
start()
{
echo -n $"Starting mongod: "
daemon --user "$MONGO_USER" $NUMACTL $mongod --setParameter textSearchEnabled=true $OPTIONS
Then you create text index and check it's existence:
db.mycoll.createIndex( { someFieldName: "text" } );
db.mycoll.getIndexes()

Related

Properly retrieve and display data from Mongoose / MongoDB .find method

I am working on a command line app in Node.js that involves retrieving results from a database (DB) using Mongoose. One important function I created just is not working no matter how hard I try and how many tutorials I go through.
The main purpose of the function is to look and see if the database (a simple word bank) has an entry containing given phrase / word.
Here is the full code setup for the particular function:
const mongoose = require('mongoose'),
mongoSettings = {
useNewUrlParser: true,
useUnifiedTopology: true
},
wordSchema = new mongoose.Schema(
{ item: String }
);
/**
* Looks for a given word or phrase in database.
* Will eventually return a boolean.
*
* #param {string} word2LookUp Word or phrase to search for
* #param {string} lang Which language list to search in [english (default), spanish, or french]
*/
const inWordBank = (word2LookUp,lang="english") => {
mongoose.connect('mongodb://localhost:27017/word-bank', mongoSettings);
mongoose.connection
.once("open",()=>{
console.log(`// ----- Searching for: "${word2LookUp}"...`);
const Word = mongoose.model('Word', wordSchema,lang);
Word.find({item: word2LookUp}, function (err, words) {
console.log(words); // <---------[ WHERE I'M HAVING TROUBLE ]
});
mongoose.connection.close();
})
.on("error", error => {
console.log(">>> Error: ",error)
mongoose.connection.close();
});
}
module.exports = {
inWordBank: inWordBank
}
This is how I am trying to execute the function on my app.js file:
const wordBank = require("./wordBank");
wordBank.alreadyRegistered("fem");
All I get in the console is:
// ----- Searching for: "fem"...
undefined
undefined
undefined
Some additional tidbits:
There's 3 documents in the particular DB in question that contain "fem" in their "item" section. That's probably why there is undefined 3 times for some odd reason.
The DB works fine when I write to it so I know it's not a connection issue
There are no other errors generated.
In my package.json file, my dependencies look like this:
"devDependencies": {
"chai": "^4.2.0",
"mocha": "^6.2.2"
},
"dependencies": {
"mongoose": "^5.7.10"
}
Is there an important piece of the puzzle I'm simply missing? Or do I have to rewrite this from square 1?
Right now you are searching for the exact value of word2Lookup. To search for documents who's item contains a string, you have to use regex.
So for wordBank.alreadyRegistered("fem"); try using wordBank.alreadyRegistered(/fem/g);.
Or, at the top of inWordBank() you can take the passed string and make a regex out of it like so: word2Lookup = new RegExp(word2Lookup, 'g');. Just put that at the top of your inWordBank() function.
Edit: There is another issue. Since the value is returning undefined, there is actually an error being thrown by MongoDB. Do console.log(err); inside the find callback and that will tell you the error.
As #chirspytoes says it is important to verify if there is no error, you can do it as follows:
Word.find({item: word2LookUp}, function (err, words) {
if(err) {
console.error(err);
return;
}
console.log(words);
});
The second thing to consider is that the results obtained with the find() method come as an array.
Example:
[
{
"item": "fem..."
},
{
"item": "...fem"
},
{
"item": "fem"
},
]

db.collection(collection).find(<query>) returns empty array as soon as query object contains properties

I'm writing my own CLI, which performs some actions against a MongoDB database using mongoose.
Everything works except for the fact that as soon as the query object is something other than {}, I get no results despite documents existing. See below for an example.
const program = require('commander');
const mongoose = require('mongoose');
const jsonParser = require('../helpers/json-parser');
program
.command('get <collection>')
.option('-q,--query <query>', 'MongoDB query object', jsonParser)
.option('-qo,--query-options [query-options]', 'MongoDB query options object', jsonParser)
.description('Returns documents from a MongoDB collection')
.action(action);
program.parse(process.argv);
function action(collection, options) {
let db;
mongoose.connect('<my-mongo-url>', { useNewUrlParser: true }).then(() => {
db = mongoose.connection.db;
console.log(options.query);
return db.collection(collection).find(options.query, options.queryOptions).toArray().then((docs) => {
console.log(docs);
mongoose.disconnect();
});
})
.catch((err) => {
if (db) {
mongoose.disconnect();
}
});
}
Running $ my-cli get users -q '{}' gives the following result:
[ { _id: 5cfe593b3bb7cb82644651f0,
email: 'foobar#gmail.com',
createdAt: 2019-06-10T13:20:59.784Z,
updatedAt: 2019-06-10T13:20:59.784Z,
role: 'user',
__v: 0 } ]
Running $ my-cli get users -q '{"_id": "5cfe593b3bb7cb82644651f0"}' gives the following result:
[]
Running $ my-cli get users -q '{"limit": 1}' gives the following result:
[]
Running $ my-cli get users -q '{"skip": 0}' gives the following result:
[]
I even tried doing db.collection(collection).find({_id: "5cfe593b3bb7cb82644651f0"}) directly in the code but it still only gives me an empty array.
I expect all of these queries to output the same thing but they don't. Why is this?
The _id in mongoDB is not string, actually it's an instance of ObjectId. So maybe you should go db.collection(collection).find({_id: ObjectId("5cfe593b3bb7cb82644651f0")}).
As for '{"limit": 1}' and '{"skip": 0}', I understand that you want to Modify the Cursor Behavior to limit or skip the search results.
However, the db.collection.find receive two params: query and projection, so passing '{"limit": 1}' or '{"skip": 0}' as the find secondary param maybe not what you want.
You are using Mongoose but not using Schemas and querying directly to MongoDB (so I don't understand the purpose of using it.). This way, you should compare the _id field with an ObjectId:
db.collection(collection).find({_id: ObjectId("5cfe593b3bb7cb82644651f0")})
or
$ my-cli get users -q '{"_id": ObjectId("5cfe593b3bb7cb82644651f0")}'
If I'm not wrong, the other queries are not running because you are passing options as query filters and you should use the -qo flag:
$ `my-cli get users -qo '{"limit": 1}'

Not able to create index using mongoose

I am building a search feature in a Node.js application which uses Mongoose, creating a full-text search index in Mongo:
postSchema = mongoose.Schema({
xx : String
.......
}).index({
'xx':'text'
});
Post = mongoose.model('Post',postSchema);
And execute the search as follows:
find = {'$text':{'$search':query}};
findScore = {'score':{'$meta':'textScore'}};
sort = {'score': {'$meta':'textScore'} };
Post.find(find, findScore).sort(sort).exec(function (err, data) {
if (err){
logging.log(err);
} else {
logging.log(data);
}
});
When I run the program, I get the following error:
'Unable to execute query: error processing query \n planner returned error: need exactly one text index for $text query'
Any help would be appreciated.
A collection can have at most one text index. You need to check it any of the text index is previously created.

How to run custom wp-cli commands using node-wp-cli?

I am using node-wp-cli to run WP-cli commands from Node.js. All inbuilt WP-cli commands works perfectly but I stuck while trying to run my custom WP-cli commands.
Is there a way to to run my custom WP-Cli commands wp MyRegisteredCommand SubCommand from node-wp-cli? like:
WP.MyRegisteredCommand.SubCommand(function(err,res){ //get response
console.log(res);
});
This is relatively easy, but requires some tweaking...
Node wp-cli uses wp cli cmd-dump to identify the available commands, but this command runs before the WordPress is loaded, so it will recognize only the in-built commands.
The tweak in short:
See WP.js, line schema(function(err,schema){.... You need to know the structure of schema, so just run some in-built command and put a breakpoint here.
Implement the schema for your commands, following the schema structure above. It will look something like this:
my_commands.js:
var schema = {
mycmd: {
mysubcmd: {
args: [ {
arg: 'arg1',
required: true,
type: 'args'
} ],
endpoint: true,
options: {
opt1: {
required: true,
type: 'param'
},
flag1: {
required: false,
type: 'flag'
},
}
},
use: 'wp mycmd mysubcmd'
}
}
module.exports.schema = schema;
Modify WP.js:
var mySchema = require('my_commands.js').schema;
...
schema(function(err,schema){
schema = _.merge(schema, mySchema); // this line added
var toMerge = function mapSchema(schema){

CompoundJS: Populating database with seed file hangs

I'm trying to populate my CompoundJS application's Mongo database with seed files, but whenever I run compound seed, the terminal hangs after my console.log statements... the database fills, but I have to kill the command with Ctrl-c.
I've tried doing compound seed harvest, but that doesn't create proper seed files, so I've decided to make my own. Here is my respective code:
db/seeds/development/Host.js (seed file)
console.log("Seeding Hosts....");
var hosts = [
{
hid: '1',
name: 'MY API',
domain: 'mydomain.com'
}
];
hosts.forEach(function(obj, err){
Host.create(obj, function(err, host){
console.log('host Added: ', host);
});
});
db/schema.js
var Host = describe('Host', function () {
property('hid', String);
property('name', String);
property('domain', String);
set('restPath', pathTo.hosts);
});
config/database.js
module.exports = {
development: {
driver: 'mongodb',
url: 'mongodb://localhost/apicache-dev'
},
test: {
driver: 'mongodb',
url: 'mongodb://localhost/apicache-test'
},
production: {
driver: 'mongodb',
url: 'mongodb://localhost/apicache-production'
}
};
Like I said, when I run compound seed, it shows both console.log statements, and it puts my data into the database, but it just hangs... never actually returning to the command line, so I'm forced to kill it with Ctrl-c. I would like to solve this problem, as I have to automate this process, and it's a bit hard automating if it's just hanging. What am I doing wrong? Any help would be appreciated!
Cross-posted.
EDIT
So when I try to use the Coffee script version that's generated from compound seed harvest:
db/seeds/development/Host.coffee
Host.seed ->
hid: '1'
name: 'MY API'
domain: 'mydomain.com'
id: "52571edd2ac9056339000001"
I get the error collection name must be a String. So I was a little curious and went to where that error was being generated... in node_modules/jugglingdb-mongodb/node_modules/mongodb/lib/mongodb/collection.js on line 103. I put a console.log(collectionName) right before that if statement and saw an interesting output...
{ hid: '1',
name: 'MY API',
domain: 'mydomain.com',
id: NaN }
So clearly it's not a string, but a hash object, and my collection's name (Host) is nowhere in sight. Seems like a bug to me.
So I finally got it to work. Apparently, there was something wrong with the auto-genned id from the harvest command, so I ended up deleting that line, and voila! Planting the seeds works like a charm. I converted the rest of my JS files to Coffee script files and everything works. Sometimes you just need to have a conversation with yourself on the Internet...
Here's my seed file:
Host.seed ->
hid: '1'
name: 'MY API'
domain: 'mydomain.com'
And doing compound seed works without hanging and populates the database. Guess Coffee script is the way to go?

Resources