MongoDB - $maxscan option - mongodb

C:\>mongo
C:\>C:\Programs\MongoDB\bin\mongo.exe
MongoDB shell version: 2.4.8
connecting to: test
Welcome to the MongoDB shell!
[test] 2014-02-26 17:09:35.933 >>> db.people.count();
9
[test] 2014-02-26 17:09:39.10 >>> db.people.find({})._addSpecial("$maxscan", 5);
{
"_id" : ObjectId("530e61be188483458f1edca7"),
"name" : "joe",
"random" : 0.7170755963306874
}
{
"_id" : ObjectId("530e61c2188483458f1edca8"),
"name" : "mark",
"random" : 0.6132313262205571
}
{
"_id" : ObjectId("530e61c7188483458f1edca9"),
"name" : "john",
"random" : 0.07292630313895643
}
{
"_id" : ObjectId("530e621c188483458f1edcaa"),
"name" : "allen",
"random" : 0.09901093109510839
}
{
"_id" : ObjectId("530e636f188483458f1edcab"),
"name" : "kevin",
"random" : 0.9719919066410512
}
{
"_id" : ObjectId("530e6375188483458f1edcac"),
"name" : "nicola",
"random" : 0.4626409418415278
}
{
"_id" : ObjectId("530e6428188483458f1edcad"),
"name" : "peter",
"random" : 0.8568310006521642
}
{
"_id" : ObjectId("530e642d188483458f1edcae"),
"name" : "tim",
"random" : 0.5209994465112686
}
{
"_id" : ObjectId("530e6437188483458f1edcaf"),
"name" : "joseph",
"random" : 0.6217151982709765
}
[test] 2014-02-26 17:09:51.76 >>>
I have 9 documents in this collection.
I am calling the find query above with
the option _addSpecial("$maxscan", 5).
And still, 9 documents are returned.
I was expecting 5 documents returned.
Why is it behaving this way?
I looked at the documentation here
http://docs.mongodb.org/manual/reference/operator/meta/maxScan/
but I don't think it provides any clues.

MongoDB is type-sensitive and case-sensitive, that means that you have to write the operator exactly as it is. You wrote like $maxscan but actually, according with the documentation is $maxScan.

Related

Text search on mongodb

I have a users collection in Mongo DB having 55L users. The collection is shared across 10 nodes.
There is a field "email" in the collection which stores the email address of the users.
I want to perform a text-based search on this field. I want to search for "mail" and the result should list all documents which have the substring "mail".
I tried with regex but it impacts performance due to collection size.
I tried creating a text index on "email" but it does not support partial search on tokens.
Collection example mentioned below
{ "_id" : ObjectId("5b90e5ffe34b5891eb4c32f6"), "email" : "anand#gmail.com" }
{ "_id" : ObjectId("5b90e64ee34b5891eb4c32f7"), "email" : "kumar.anand#hotmail.com" }
{ "_id" : ObjectId("5b90e65ae34b5891eb4c32f8"), "email" : "ankit#gmail.com" }
{ "_id" : ObjectId("5b90e661e34b5891eb4c32f9"), "email" : "rahul#rediff.com" }
{ "_id" : ObjectId("5b90e67de34b5891eb4c32fa"), "email" : "prachi#gmail.com" }
{ "_id" : ObjectId("5b90f0ab46ef1951e6afb822"), "email" : "bb#yahoo.com", "name" : "ankit" }
{ "_id" : ObjectId("5b965d4ad5bc80bda9885181"), "email" : "amit#gmail.com", "rating" : [ 5, 6 ] }
{ "_id" : ObjectId("5b965d56d5bc80bda9885182"), "email" : "amit33#gmail.com", "rating" : [ 2, 4 ] }
{ "_id" : ObjectId("5b965d60d5bc80bda9885183"), "email" : "amit11#gmail.com", "rating" : [ 12, 14 ] }
{ "_id" : ObjectId("5b966cf1f12e2344dc5942e5"), "email" : "avin11#gmail.com", "new_rating" : { "id" : [ 5, 6 ] } }
{ "_id" : ObjectId("5b966cfdf12e2344dc5942e6"), "email" : "avin22#gmail.com", "new_rating" : { "id" : [ 2, 4 ] } }
{ "_id" : ObjectId("5b966d06f12e2344dc5942e7"), "email" : "avin33#gmail.com", "new_rating" : { "id" : [ 12, 14 ] } }
{ "_id" : ObjectId("5b986afaf12e2344dc5942e8"), "email" : "Sachin#hotmail.com", "name" : "Sachin" }
Kindly suggest how to perform the search query
Hi and welcome to Stack overflow community..
I think you can still use a regex, but you should have an index on the email field to have better performance.
Read more about regex and indexes on mongo DB here: https://docs.mongodb.com/manual/reference/operator/query/regex/#index-use
I suggest using Explain Results to make sure your query uses the index you added.
Hope this helps.

How to query an array of _id in MongoDB?

I have collection Collection1 and I need to fetch an array like: [id1, id2, id3, ...] (array which consist of _id`s for every element in this collection). Is there any way to do this query with MongoDB tools ? Thank you!
You will have to use cursor.toArray() function on result of find having a projection document projecting only _id i.e ObjectId() value
MongoDB Enterprise > db.users.find().pretty()
{
"_id" : ObjectId("570e1d465a44f125ef156791"),
"name" : "Ritesh Talreja",
"age" : 22,
"gender" : "M"
}
{
"_id" : ObjectId("570e1e1d5a44f125ef156792"),
"name" : "Saloni",
"age" : 21,
"gender" : "F"
}
{
"_id" : ObjectId("570e1e485a44f125ef156793"),
"name" : "abcd",
"age" : 22,
"gender" : "M"
}
{
"_id" : ObjectId("570e28d45a44f125ef156794"),
"name" : "Saloni",
"age" : 21,
"gender" : "F"
}
{ "_id" : 123 }
MongoDB Enterprise > db.users.find({}, {_id:1}).toArray()
[
{
"_id" : ObjectId("570e1d465a44f125ef156791")
},
{
"_id" : ObjectId("570e1e1d5a44f125ef156792")
},
{
"_id" : ObjectId("570e1e485a44f125ef156793")
},
{
"_id" : ObjectId("570e28d45a44f125ef156794")
},
{
"_id" : 123
}
]
MongoDB Enterprise >
As an addition you can also use:
MongoDB Enterprise > db.users.distinct("_id")
[
123,
ObjectId("570e1d465a44f125ef156791"),
ObjectId("570e1e1d5a44f125ef156792"),
ObjectId("570e1e485a44f125ef156793"),
ObjectId("570e28d45a44f125ef156794")
]
MongoDB Enterprise >

Error in Projection using find() method

I am total newbie to MongoDB. I was trying out basic stuff in mongo, when I encountered a problem. I searched for it, but not able to find any satisfactory answer.
I have a very simple collection named "users" having names and age of some persons. Below is output of db.users.find()
{ "_id" : ObjectId("566acc0442fea953b8d94a7e"), "name" : "gabriel", "age" : 22 }
{ "_id" : ObjectId("566acc0442fea953b8d94a7f"), "name" : "andy", "age" : 10 }
{ "_id" : ObjectId("566acc1342fea953b8d94a80"), "name" : "henry", "age" : 27 }
{ "_id" : ObjectId("566acc1342fea953b8d94a81"), "name" : "william", "age" : 19 }
{ "_id" : ObjectId("566acc3242fea953b8d94a82"), "name" : "sandra", "age" : 20 }
{ "_id" : ObjectId("566acc3242fea953b8d94a83"), "name" : "tom", "age" : 24 }
Now, I am trying to apply different projection on it. First two are:
db.users.find({}, {"name":1, "age":1})
{ "_id" : ObjectId("566acc0442fea953b8d94a7e"), "name" : "gabriel", "age" : 22 }
{ "_id" : ObjectId("566acc0442fea953b8d94a7f"), "name" : "andy", "age" : 10 }
{ "_id" : ObjectId("566acc1342fea953b8d94a80"), "name" : "henry", "age" : 27 }
{ "_id" : ObjectId("566acc1342fea953b8d94a81"), "name" : "william", "age" : 19 }
{ "_id" : ObjectId("566acc3242fea953b8d94a82"), "name" : "sandra", "age" : 20 }
{ "_id" : ObjectId("566acc3242fea953b8d94a83"), "name" : "tom", "age" : 24 }
db.users.find({}, {"name":0, "age":0})
{ "_id" : ObjectId("566acc0442fea953b8d94a7e") }
{ "_id" : ObjectId("566acc0442fea953b8d94a7f") }
{ "_id" : ObjectId("566acc1342fea953b8d94a80") }
{ "_id" : ObjectId("566acc1342fea953b8d94a81") }
{ "_id" : ObjectId("566acc3242fea953b8d94a82") }
{ "_id" : ObjectId("566acc3242fea953b8d94a83") }
are working just fine, but
db.users.find({}, {"name":0, "age":1})
Error: error: {
"$err" : "Can't canonicalize query: BadValue Projection cannot have a mix of inclusion and exclusion.",
"code" : 17287
}
is failing and giving error as shown above. I searched that problem may arise if there is conflicting conditions in projection, but I don't think there is something like that in my method call. Is there some rule like value of fields in find method should be either all ZERO or all ONE, but cannot be both. Please help.
If you want your query to return only the age, your projection must include only the fields you want to have. Not the one you don't want:
db.projection.find({}, {_id:0, age:1})
Exception for _id, you can specify to not include it.
Result
{
"age": 22
}
From the documentation:
A projection cannot contain both include and exclude specifications, except for the exclusion of the _id field. In projections that explicitly include fields, the _id field is the only field that you can explicitly exclude.

search document values within a text in mongodb

I need to find all document values which are within a text/string:
Example:
Imagine I have the tag collection with the following documents:
db.tag.find()
{ "_id" : ObjectId("536f7107c55b2acc61000bc8"), "name" : "star" }
{ "_id" : ObjectId("536f710fc55b2acc61000bc9"), "name" : "star wars" }
{ "_id" : ObjectId("536f7117c55b2acc61000bca"), "name" : "spider" }
{ "_id" : ObjectId("537087d16ac5b5f6f58f0b1b"), "name" : "starting" }
I need something like this (example in mongodb shell):
db.tag.find({"name": { $subStrOF: "star wars episode VII" }})
returning this:
{ "_id" : ObjectId("536f7107c55b2acc61000bc8"), "name" : "star" }
{ "_id" : ObjectId("536f710fc55b2acc61000bc9"), "name" : "star wars" }
Any idea?
Thank you very much
Firstly, Start the mongod process with command line options
--setParameter textSearchEnabled=true
Example:
mongod --setParameter textSearchEnabled=true
Then in your mongo shell, create an index for name in tag collection
db.tag.ensureIndex({name : "text"});
Now you can query using text:
db.tag.runCommand("text", {search : "star wars episode"});
This will return you something like this
{
"queryDebugString" : "star||||||",
"language" : "english",
"results" : [
{
"score" : 1.1,
"obj" : {
"_id" : ObjectId("536f7107c55b2acc61000bc8"),
"name" : "star"
}
},
{
"score" : 0.75,
"obj" : {
"_id" : ObjectId("536f710fc55b2acc61000bc9"),
"name" : "star wars"
}
}
],
"stats" : {
"nscanned" : 2,
"nscannedObjects" : 0,
"n" : 2,
"nfound" : 2,
"timeMicros" : 152
},
"ok" : 1
}
To get only the results:
db.tag.runCommand("text", {search : "star wars episode"}).results
I have tested it with my local DB and it works fine. please check it
For more info about text : Mongo DOCs
BTW from mongoDB 2.6: DOCS
db.tag.find({$text : {$search : "star wars episode VII"}});
I got it working using $where, example below:
Command:
db.tag.find({$where:"'star wars episode VII'.search("star") >= 0"})
The output:
{ "_id" : ObjectId("536f7107c55b2acc61000bc8"), "name" : "star" }
{ "_id" : ObjectId("536f710fc55b2acc61000bc9"), "name" : "star wars" }
Hope it helps

mongodb $maxScan didn't equals limit

This is my first question on stack overflow, I am so happy and await your answers. My question is:
When I use MongoDB Query Selectors, I want limit results. But $maxScan is not work as I want.
---------This is What I want result.
db.post.find({query:{status:"publish"},$orderby:{date:-1}},{status:1,name:1,date:1,$slice:2}).limit(3)
{ "_id" : ObjectId("519262580cf21fb1647fb765"), "date" : ISODate("2013-05-14T16:12:08.600Z"), "status" : "publish", "name" : "关于多说" }
{ "_id" : ObjectId("519254ad0cf2f064f6ecef82"), "date" : ISODate("2013-05-14T15:13:49.017Z"), "status" : "publish", "name" : "回顾<蜗居>的100句经典台词" }
{ "_id" : ObjectId("519254690cf2f064f6ecef81"), "date" : ISODate("2013-05-14T15:12:41.462Z"), "status" : "publish", "name" : "女人脱光了是什么" }
-----------This is the results I use $maxScan
db.post.find({query:{status:"publish"},$maxScan:3,$orderby:{date:-1}},{status:1,name:1,date:1})
{ "_id" : ObjectId("518e6c690cf21a363df2956e"), "date" : ISODate("2013-05-11T16:06:01.341Z"), "status" : "publish", "name" : "淘宝新店,充值任务" }
I find may be the $maxScan didn't like limit(). it first limit the collection data and then execute the query! but this is not I want. Is anything i wrong? please help.Thanks
--------------All results
db.post.find({query:{},$orderby:{date:-1}},{status:1,name:1,date:1})
{ "_id" : ObjectId("519262580cf21fb1647fb765"), "date" : ISODate("2013-05-14T16:12:08.600Z"), "status" : "publish", "name" : "关于多说" }
{ "_id" : ObjectId("519254ad0cf2f064f6ecef82"), "date" : ISODate("2013-05-14T15:13:49.017Z"), "status" : "publish", "name" : "回顾<蜗居>的100句经典台词" }
{ "_id" : ObjectId("519254690cf2f064f6ecef81"), "date" : ISODate("2013-05-14T15:12:41.462Z"), "status" : "publish", "name" : "女人脱光了是什么" }
{ "_id" : ObjectId("518ee61a0cf22bd326d60215"), "date" : ISODate("2013-05-12T00:45:14.295Z"), "status" : "publish", "name" : "JSTL日期格式化用法(转载)" }
{ "_id" : ObjectId("518e6c690cf21a363df2956e"), "date" : ISODate("2013-05-11T16:06:01.341Z"), "status" : "publish", "name" : "淘宝新店,充值任务" }
{ "_id" : ObjectId("518e21c90cf21a363df2956d"), "date" : ISODate("2013-05-11T10:47:37.803Z"), "status" : "draft", "name" : "一夜没睡" }
{ "_id" : ObjectId("518df75d0cf21a363df2956c"), "date" : ISODate("2013-05-11T07:46:37.726Z"), "status" : "draft", "name" : "飞娥入侵" }
{ "_id" : ObjectId("518d80630cf21a363df2956b"), "date" : ISODate("2013-05-10T23:18:59.323Z"), "status" : "publish", "name" : "Java的日期格式化常用方法" }
To return only the top results, you should use limit(), which will limit the amount of results returned from the cursor. This is commonly used with skip() to paginate the results.
It's not explained very clearly in the docs, but $maxScan as the name suggests limits the number of documents the query will examine. Presumably your query is examining some documents which don't meet the criteria (with status != publish) and then discarding them.
Do you have an index on status? It's possible that could help the query return the results you want while scanning fewer documents, but I still think limit() is what you want.