6

I'm using mongo db nodejs and mongoose.

I would like to use mongodb new text search.

Trying to use mongoose-text-search like aaronheckmann advised but I keep getting an error.

var mongoose = require("mongoose");
var Schema  = mongoose.Schema;
var ObjectId = Schema.ObjectId;
var Items = new Schema({
   type            : { type : String , default:""},
    color           : { type : [String] , default:""},
   category_A      : { type : String , default:""},
    category_B      : { type : String , default:""},
    category_C      : { type : String , default:""},
});
var textSearch = require("mongoose-text-search");
Items.plugin(textSearch);
var ItemModel = mongoose.model('Item', Items);
Items.index({
    type            :"text",
    color           :"text",
   category_A      :"text",
    category_B      :"text",
    category_C      :"text"
},
   {
        name: "best_match_index",
       weights: {
            type: 5,  
            color:   4,
      }
    }
)
ItemModel.textSearch('D', function (err, output) {
    if (err) 
    console.log(err);
    else
    console.log(output)
})

When running this I get:

no text index for: db.items

Thanks!

Liatz
  • 4,997
  • 7
  • 28
  • 33

3 Answers3

12

You have to add the plugin to the schema before registering the schema as a model.

UPDATED

Likewise, you need to define the index on the schema before registering the model. So re-order that section of your code like this:

var textSearch = require("mongoose-text-search");
Items.plugin(textSearch);
Items.index({
    type            :"text",
    color           :"text",
    category_A      :"text",
    category_B      :"text",
    category_C      :"text"
}, {
    name: "best_match_index",
    weights: {
        type: 5,  
        color: 4
    }
});
var ItemModel = mongoose.model('Item', Items);

Note that you also need to connect mongoose to the database via a mongoose.connect call which I don't see anywhere, but I'm assuming you're doing that outside of the scope of this code. Here's the full code I used to confirm this works:

var mongoose = require("mongoose");
var Schema  = mongoose.Schema;
var ObjectId = Schema.ObjectId;
var Items = new Schema({
    type            : { type : String , default:""},
    color           : { type : [String] , default:""},
    category_A      : { type : String , default:""},
    category_B      : { type : String , default:""},
    category_C      : { type : String , default:""},
});
var textSearch = require("mongoose-text-search");
Items.plugin(textSearch);
Items.index({
    type            :"text",
    color           :"text",
    category_A      :"text",
    category_B      :"text",
    category_C      :"text"
}, {
    name: "best_match_index",
    weights: {
        type: 5,
        color: 4,
    }
});
var ItemModel = mongoose.model('Item', Items);

mongoose.connect('mongodb://localhost/test', function (err) {
  ItemModel.textSearch('D', function (err, output) {
    if (err)
      console.log(err);
    else
      console.log(output);
    mongoose.disconnect();
  });
});

The created text search index looks like this in the shell:

test> db.items.getIndexes()
[
  {
    "v": 1,
    "key": {
      "_id": 1
    },
    "ns": "test.items",
    "name": "_id_"
  },
  {
    "v": 1,
    "key": {
      "_fts": "text",
      "_ftsx": 1
    },
    "ns": "test.items",
    "name": "best_match_index",
    "weights": {
      "category_A": 1,
      "category_B": 1,
      "category_C": 1,
      "color": 4,
      "type": 5
    },
    "background": true,
    "safe": null,
    "default_language": "english",
    "language_override": "language",
    "textIndexVersion": 1
  }
]
JohnnyHK
  • 305,182
  • 66
  • 621
  • 471
  • great that solves the previos error but I still get an error - no text index for: db.items. As I've written in the question I do declare the test index. What's wrong? Thanks! – Liatz Apr 28 '13 at 10:36
  • @Liatz You need to call `index` on the schema before registering it as a model as well. See updated answer. – JohnnyHK Apr 28 '13 at 14:05
  • running the code above still pops an error - [Error: no text index for: db.items] – Liatz Apr 29 '13 at 08:21
  • @Liatz Are you running a 2.4+ version of Mongo? Have you enabled text search in your Mongo server? Does the `best_match_index` show up in the `db.items.getIndexes()` results in the shell? – JohnnyHK Apr 29 '13 at 11:57
  • MongoDB shell version: 2.4.2 low. Number of files is 256, should be at least 1000 Sat Apr 27 15:02:42.366 [initandlisten] Index { v: 1, key: { type: "text", color: "text", category_A: "text", category_B: "text", category_C: "text" }, ns: "db.items", name: "type_text_color_text_category_A_text_category_B_text_category_C_text", sparse: false, background: false } claims to be of type 'text', which is either invalid or did not exist before v2.4. See the upgrade section: http://dochub.mongodb.org/core/upgrade-2.4 – Liatz Apr 29 '13 at 15:47
  • > db.items.getIndexes() [{"v" : 1,"key" : {"_id" : 1},"ns" : "db.items","name" : "_id_"}, {"v" : 1,"key" : {"type" : "text","color" : "text","category_A" : "text","category_B" : "text","category_C" : "text"}, "ns" : "db.items","name" : "type_text_color_text_category_A_text_category_B_text_category_C_text","sparse" : false, "background" : false}] – Liatz Apr 29 '13 at 15:48
  • @Liatz Hmm...I'm using Mongo 2.4.3 and Mongoose 3.6.8 and the index looks very different. Maybe upgrade to 2.4.3, drop the index and let Mongoose re-create it. – JohnnyHK Apr 29 '13 at 16:47
  • @JohnnyHK i wanted to direct your attention to http://stackoverflow.com/questions/19894849/error-text-search-not-enabled-in-moongose-text-search-plugin questino as well. – Sangram Singh Nov 10 '13 at 20:39
5
npm install mongoose-text-search

https://github.com/aheckmann/mongoose-text-search

A good place to discover additional mongoose functionality is http://plugins.mongoosejs.com

aaronheckmann
  • 10,625
  • 2
  • 40
  • 30
  • 1
    Is this plugin still needed or is text search supported now with mongoose... a bit confused since this is over a year and a half ago – Lion789 Nov 04 '14 at 16:06
2

As far as I'm aware, most drivers haven't implemented text search commands/functions so the only way to call it is using the runCommand function.

You need to make sure you enable it on your database first though (and obviously create a text index).

http://docs.mongodb.org/manual/tutorial/enable-text-search/

or runtime

db.adminCommand( { setParameter : 1, textSearchEnabled : true } )
sambomartin
  • 6,663
  • 7
  • 40
  • 64
  • My question is, if the only way is runCommand, how can I use runCommand in mongoose? looks like mongoose doesn't support it, tried executeDbCommand and it doesn't work. – Liatz Apr 14 '13 at 07:26