My User collection contains the following documents:
{"_id" : 1, point_count: "12"},
{"_id" : 2, point_count: "19"},
{"_id" : 3, point_count: "13"},
{"_id" : 4, point_count: "1233"},
{"_id" : 5, point_count: "1"},
... and about 1000 more
My question is: Is it possible to show ranking of each user based on point_count field when I search by id? let say I use this query to find user with id = 4
db.User.find({_id: 4})
let assume highest point_count in my entire collection is 1233, I'm hoping to get this result
{"_id" : 4, point_count: "1233", rank: 1}
rank 1 because 1233 is the highest point_count
or when I search user with id = 5, my expect result should be
{"_id" : 5, point_count: "1", rank: 1000..something}
1000..something because it is the lowest rank and there are around 1000+ id in the document.
Thank you all so much for helping me here!
Related
I am new to mongodb so forgive me if this question has an obvious answer or if it's a little unclear but I have searched for hours now and I have no idea why this isn't working. I want to get all users(collection name) with a red shirt or is over the age of 20 which I can get, but I only want to print out the users id and name.
Example of document in collection:
{"_id" : ObjectId(hy65fi6152g8off589992y),
"id" : 02451,
"age" : 20,
"shirt" : "red",
"name" : "bob"}
Query I thought would work:
db.users.find({
$or:[
{"shirt" : "red"}, {"age" : {$gt:20}}
]
}
{id : 1, name: 1, _id: 0}
)
I'm trying several queries in mongodb. Each document of my colelction is like this :
{
"_id" : 1,
"name" : 1,
"isReferenceProteome" : 1,
"isRepresentativeProteome" : 1,
"component" : 1,
"reference" : 1,
"upid" : 1,
"modified" : 1,
"taxonomy" : 1,
"superregnum" : 1,
"description" : 1,
"dbReference" : 1
}
the "reference" field has nested fields, one is "authorList", an array containing 'name' fields.
"reference" {
"authorList" [
{"name": "author1"},
{"name": "author2"},
{"name": "author3"} ...etc...
]
}
I have stored in a variable the result of the following query :
var testing = db.mycollection.find({'reference.authorList.30': {$exists: true}})
which stores all documents where the authorList is at least 30 names long.
Then I wanted to use distinct() on this variable, in order to have the distinct names of all authors :
testing.distinct("reference.authorList.name")
I tried this way because my first query returned an empty array :
db.mycollection.distinct( "reference.authorList.name", {"reference.authorList.name.30": {$exists: true}} )
I'm also trying whit $where command, but I got syntaxError for now.
What I am missing ?
Thanks.
Use
db.head_human_prot.distinct( "reference.authorList.name", {"reference.authorList.30": {$exists: true}} )
instead of
db.head_human_prot.distinct( "reference.authorList.name", {"reference.authorList.name.30": {$exists: true}} )
Silly me...
I have next document structure and insertion rules.
Document : {_id : 1, priority : 1.89, etc...}.
Rules : the field priority should be unique, the insert operation must affect the smallest number of elements.
I want to calculate new priority(Priority that will be displayed for user, 1,2,3,etc..) on db level.In SQL i can execute the next query(Based on Subquery)
Select *, (Select Count(fldName) from tableName where priority <= tn.priority) as priority from tableName as tn
In documentation i didn't found information about something similar, $project, $group, $let, etc...
Could you please give me advice about my problem!)
P.S
I can't store the data in normal form, they very often change and affect many elements.
Example :
{_id : 1, priority : 1, etc...}
{_id : 2, priority : 2, etc...}
{_id : 3, priority : 3, etc...}
insert in the middle
{_id : 4, priority : 2, etc...}
I should switch another elements
{_id : 1, priority : 1, etc...}
{_id : 4, priority : 2, etc...}
{_id : 2, priority : 3, etc...}
{_id : 3, priority : 4, etc...}
I have document with nested document reviews:
{
"_id" : ObjectId("53a5753937c2f0ef6dcd9006"),
"product" : "Super Duper-o-phonic",
"price" : 11000000000,
"reviews" : [
{
"user" : "fred",
"comment" : "Great!",
"rating" : 5
},
{
"user" : "Tom",
"comment" : "Great again!",
"rating" : 5
},
{
"user" : "Tom",
"comment" : "I agree with fred somewhat",
"rating" : 4
}
]
}
I want to find only those reviews whose rating is 5.
Final query should select product price and two documents from reviews whose rating is 5.
The last query I tried is :
db.testData.find({'reviews':{$elemMatch:{'rating':{$gte:5}}}}).pretty()
It's strange but it doesn't work.
How to do this in mongodb?
If you only want a single sub-doc from reviews whose rating is 5, you can use the $ positional projection operator to include the first element of reviews that matches your query:
db.test.find({'reviews.rating': 5}, {product: 1, price: 1, 'reviews.$': 1})
If you want all reviews elements with a rating of 5 (instead of just the first) you can use aggregate instead of find:
db.test.aggregate([
// Only include docs with at least one 5 rating review
{$match: {'reviews.rating': 5}},
// Duplicate the docs, one per reviews element
{$unwind: '$reviews'},
// Only include the ones where rating = 5
{$match: {'reviews.rating': 5}},
// Only include the following fields in the output
{$project: {product: 1, price: 1, reviews: 1}}])
Take a look up here: MongoDB - how to query for a nested item inside a collection?
Just in case you thought about this:
If you try to accomplish this with $elemMatchit will jsut return the first matching review.
http://docs.mongodb.org/manual/reference/operator/projection/elemMatch/
I have a DB structure like below:
{
"_id" : 1,
"comments" : [
{
"_id" : 2,
"content" : "xxx"
}
]
}
I update a new subdocument in the comments feild. It is OK.
db.test.update(
{"_id" : 1, "comments._id" : 2},
{$push : {"comments.$.comments" : {_id : 3, content:"xxx"}}}
)
after that the DB structure:
{
"_id" : 1,
"comments" : [
{
"_id" : 2,
"comments" : [
{
"id" : 3,
"content" : "xxx"
}
],
"content" : "xxx"
}
]
}
But when I update a new subdocument in the comment field that _id is 3, There is a error:
db.test.update(
{"_id" : 1, "comments.comments.id" : 3},
{$push : {"comments.comments.$.comments" : {id : 4, content:"xxx"}}}
)
error message:
can't append to array using string field name: comments
Well, it makes total sense if you think about it. MongoDb has the advantage and the disadvantage of solving magically certain things.
When you query the database for a specific regular field like this:
{ field : "value" }
The query {field:"value"} makes total sense, it wouldn't in case value is part of an array but Mongo solves it for you, so in case the structure is:
{ field : ["value", "anothervalue"] }
Mongo iterates through all of them and matches "value" into the field and you don't have to think about it. It works perfectly.. at only one level, because it's impossible to guess what you want to do if you have multiple levels
In your case the first query works because it's the case in this example:
db.test.update(
{"_id" : 1, "comments._id" : 2},
{$push : {"comments.$.comments" : {_id : 3, content:"xxx"}}}
)
Matches _id in the first level, and comments._id at the second level, it gets an array as a result but Mongo is able to solve it.
But in the second case, think what you need, let's isolate the where clause:
{"_id" : 1, "comments.comments.id" : 3},
"Give me from the main collection records with _id:1" (one doc)
"And comments which comments inside have and id=3" (array * array)
The first level is solved easily, comments.id, the second is not possible due comments returns an array, but one more level is an array of arrays and Mongo gets an array of arrays as a result and it's not possible to push a document into all the records of the array.
The solution is to narrow your where clause to obtain an unique document in comments (could be the first one) but it's not a good solution because you never know what is the position of the document you're looking for, using the shell I think the only option to be accurate is to do it in two steps. Check this query that works (not the solution anyway) but "solves" the multiple array part fixing it to the first record:
db.test.update(
{"_id" : 1, "comments.0.comments._id" : 3},
{$push : {"comments.0.comments.$.comments" : {id : 4, content:"xxx"}}}
)