I'm trying to utilize MongoDB 2.4 experimental text search feature from within nodejs. The only problem is, native nodejs mongo drivers don't seem to support collection-level runCommand, as far as I can tell.
The Mongo shell syntax looks like this:
db.collection.runCommand( "text", { search : "Textvalue" } );
There is a db.command / db.executeDbCommand function it appears, but I don't know how to choose a collection and run the text command using it (if it is possible), as it needs to be on the collection level and not the db level.
Any help would be appreciated
I managed to get it working through a combination of Asya Kamsky's comment, by utilizing
this.db.command({text:"collection" , search: "phrase" }).
The problem was it isn't returned like a standard result so a toArray() call was failing. Instead, I put the callback directly inside:
this.db.command({text:"collection" , search: "phrase" }, function(err, cb){
Related
I don't find much information about this problem to solve.
On my mongodb I create a collection every 60 seconds with the name "test "+ date.now(). So far everything works ok. It creates me different collections with the name test XXXXXX1, test XXXXX2 etc.
I have problems with the mongoose.find() method. I can't find my last created collection.
let test = mongoose.model('test' + date.now(), Schema);
test.find({}, function (err, response) {});
How do I find the latest collection in stream? Thank you!
Mongo ,By default , does not support sequence .
for that purpose you're going to have to add specific field for sorting or sort your fields based on your current field properties.
After that you have to use .sort() cursor method :
Collection.find().sort([...]);
Read this article for more info
TLDR
Is there a way to limit queryByExample to a collection in NodeJS?
Problem faced
I have a complex query with some optional fields (i.e. sometimes some search fields will be omitted). So I need to create a query dynamically, e.g. in JSON. QueryByExample seems to be the right tool to use here as it gives me that flexibility to pass a JSON. However my problem is that I would like to limit my search to only one collection or directory.
e.g. I was hoping for something like
searchJSON = {
title: { $word: "test" },
description: { $word: "desc" }
};
//query
db.documents.query(qb.where(
qb.collection("collectionName"),
qb.byExample(searchJSON)
)).result()...
In this case searchJSON could have been built dynamically, for example maybe sometimes title may be omitted from the search.
This doesn't work because the query builder only allows queryByExample to be the only query. But I'd instead like to built a dynamic search query which is limited to a collection or directory.
At present, I think you would have to express the query with QueryBuilder instead of Query By Example using
qb.and([
qb.collection('collectionName'),
qb.word('title', 'test'),
qb.word('description', 'desc')
])
See http://docs.marklogic.com/jsdoc/queryBuilder.html#word
That said, it should be possible for the Node.js API to relax that restriction based on the fixes in MarkLogic 9.0-2
Please file an issue on https://github.com/marklogic/node-client-api
I'm using Node.js + mongodb. I have few documents in my collection and i want to know does my collection have any document matched my condition. Of course i can simply use
myModel.find({ myField: someValue }) and check is anything comes or not. But i want to use solution like sql provides exists keyword? Help me, please
Edit: my bad. I forget to tell that "performance first".
MongoDB's $exists actually doesn't help you very much to find out if a certain document exists in your collection. It is used for example to give you all documents that have a specific field set.
MongoDB has no native support for an sql like exists. What you can use, however, is myModel.findOne({ myField: someValue }) and then check if it is null.
To enhance performance you can tell MongoDB to only load the object id via projection, like this:
myModel.findOne({ myField: someValue }, {_id: 1})
There is an exist mechanism in mongodb, I'll demonstrate a sample below.
For example below, I'm looking for records that have tomato.consensus fields and that it's empty, so I can delete them or avoid them. In case I was looking for "tomato.consensus": Dublin, I'd change Null to Dublin, to match that.
I hope this is helpful, if not fire away any questions
tomato
----consensus
db.movieDetails.updateMany({$and: [
{"tomato.consensus": {$exists: true} },
{"tomato.consensus": null} ] },
]})
In MongoDB 2.6, the text-search is supposedly production ready and we can now use skip. I'd like to use text-search and skip for pagination in my, but I'm not yet sure how to implement it.
Right now, I'm using Mongoose and the Mongoose-text-search plugin, but I don't believe either of them support skip in MongoDB's text search, so I guess I'll need to use the native MongoClient...
My app connects to the database via Mongoose using:
//Bootstrap db connection
var db = mongoose.connect(config.db, function(e) {
Now, how can I use the native MongoClient to execute a full text search for my Products model, with a skip parameter. Here is what I had using Mongoose and Mongoose-text-search, but there is no way to add in skip:
Product = mongoose.model('Product')
var query = req.query.query;
var skip = req.query.skip;
var options = {
project: '-created', // do not include the `created` property
filter: filter, // casts queries based on schema
limit: 20,
language: 'english',
lean: true
};
Product.textSearch(query, options, function (err, response) {
});
The main difference introduced in 2.6 versions of MongoDB is that you can issue a "text search" query using the standard .find() interface so the old methods for textSearch would no longer need to be applied. This is basically how modifiers such as limit and skip can be applied.
But keep in mind that as of writing the current Mongoose dependency is for an earlier version of the MongoDB node driver that existed prior to the release of MongoDB 2.6. As Mongoose actually wraps the main methods and does some syntax checking of it's own, it is probably likely ( as in untried by me ) that using the Mongoose methods will currently fail.
So what you will need to do is get the underlying driver method for .find(), and also now use the $text operator instead:
Product.collection.find(
{ "$text": { "$search": "term" } },
{ "sort": { "score": { "$meta": "textScore" } }, "skip": 25, "limit": 25 },
function(err,docs) {
// processing here
});
Also noting that $text operator does not sort the results by "score" for relevance by default, but this is passed to the "sort" option using the new $meta operator, which is also introduced in MongoDB 2.6.
So alter your skip and limit values and you have paging on text search results and with a cursor. Just be wary of large data returns as skip and limit are not really efficient ways to move through a large cursor. Better to have another key where you can range match, even though counter-intuitive to "relevance matching".
So, text search facilities are a bit "better" but not "perfect". As always, if you really need more and/or more performance, look to an external solution.
Feel free to try a similar operation with the Mongoose implementation of .find() as well. But have my reservations from past experience that there is generally some masking and checking going on there, so hence the description of usage with the "native" node driver.
I'm using the Mongoose-Text-Search plugin (https://github.com/aheckmann/mongoose-text-search) to search through my mongodb database, but I'm getting a really confusing error message I've never seen before.
error: name=MongoError, ok=0, errmsg=error processing query: ns=testdb.data limit=100 skip=0
Tree: TEXT : query=test, language=, tag=NULL
Sort: { $s: { $meta: "textScore" } }
Proj: { $s: { $meta: "textScore" } }
planner returned error: failed to use text index to satisfy $text query (if text index is compound, are equality predicates given for all prefix fields?)
Can someone explain what this means? I think I'm using the text-search plugin correctly, but I can't for the life of me figure out what's wrong here.
Thanks!
It looks like you created COMPOUND full text search index in Mongodb. And because of this you have to request data from full text search index together with other field. Look here for details: http://docs.mongodb.org/manual/tutorial/limit-number-of-items-scanned-for-text-search/
There are some restrictions like you can't use $gt/$gte/$lt/$lte/$in/$type composed with $and/$or etc for the predicated field. Details here: https://jira.mongodb.org/browse/SERVER-13801
Upgrade to Mongo 2.6.4 and through away Mongoose-Text-Search plugin. The plugin was useful ONLY for Mongo 2.4.x and absolutely redundant for the modern Mongo version. Just use find() method for full text search.