Mongodb Query with conjoined data points - mongodb

I'm trying to create a query that can pull this information from my database using just the type score when it's less than 70 and when it's of type exam:
{"_id":0,"name":"aimee Zank",
"scores":[{"score":1.463179736705023,"type":"exam"},
{"score":11.78273309957772,"type":"quiz"},{"score":35.8740349954354,"type":"homework"}]}
I'm not getting any errors and it's turning up blank. Here's the query I'm trying to use:
db.students.find({"scores":[{"score":{$lt:70},"type":"exam"}]}).pretty
Any help would be appreciated :)

That is not how you match elements inside array. Use $elemMatch :
db.students.find({"scores":{$elemMatch:{score:{$lt:70},type:"exam"}}})
Update:
OP marked the post as "not answered" and then come with twisted requirement. Going forward, make sure you post a seperate question for your entirely new requirements or state your problem properly, dont extend it as the time flies. However, here's the filter query using aggregation framework:
db.collection.aggregate([
{$addFields:{scores:{$filter:{
input:"$scores",
as:"score",
cond:{$and:[{$eq:["$$score.type","exam"]},{$lt:["$$score.score",70]}]}
}}}}
])
This filters all exams that have score less than 70.

Related

MongoDB get all documents, sort by a field and add ordering field based on the sorting

I am trying to sort the result of my mongoDB query and add a ranking based on that sorting. Currently I only call .find().sort({total: 1}) and this gives me the correct ordering of the documents. But is it possible to "add a field" based on that sorting (basically a ranking field, starting from 1 and counting up)? I tried googling but didnt found anything that suits for this purpose.
Thanks in advance.

Need help querying distinct combinations of nested fields

Desired result
I am trying to query my collection and obtain every unique combination of a batch and entry code. I don't care about anything other than these fields, the parent objects do not matter to me.
What I have tried
I tried running:
db.accountant_ledgers.aggregate( [ {"$group": { "_id": { entryCode: "$actions.entry.entryCode", batchCode: "$actions.entry.batchCode" } } } ]);
Problem
I get unexpected results when I run that query. I'm looking for a list of every unique combination of batch and entry codes, but instead I get a list of arrays? Perhaps these are the results I'm looking for, but I have no idea how to read them if they are.
Theory
I think perhaps this could have to do with the fact that these fields are nested. Each object has several actions, each action has several entries. I believe that the result from that query is just the aggregated entry and batch codes found in each object. I don't know how long the list of results is, but I'd guess it's the same number as the total number of objects in my collection (~90 million).
EDIT: I found out that there are only 182 results from my query, which is clearly significantly smaller than 90 million. My new theory is that it has found all unique objects, with the criteria for "uniqueness" being the list of the batch and entry codes that appear in their actions, which makes sense. There should be a lot of repetition in the collection.
Question
How can I achieve the result I'm looking for? I'm expecting something like:
FEE, MG
EXN, WT
ACH, 9C
...etc
Notes
I apologize if this is a bad question, I'm not sure how else to frame it. Let me know if I can improve my question at all.
Picture below shows the results of the query.
EDIT FOR ADDITIONAL INFORMATION
I can't share any sample documents, but the general structure of the data is shown (crudely) in the below image. Each Entity has several Actions, each Action has one Entry and each Entry has one Batch code and one Entry code.
List item
You are getting a list of documents (each is a map or a hash), not a list of arrays.
The GUI you are using is trying to show you the contents of each document on the top level which is maybe what is confusing.
If you run the query in mongo shell you should see a list of documents.
It looks like your inputs are documents where entry code and batch code are arrays, if so:
Edit your question to include sample documents you are querying as text
You could use $unwind to flatten those arrays before using $group.

Execute multiple queries at same time, if the all the queries are valid then only I should get the response in MongoDB

I am trying to execute 2 queries at the same time, for example, refer below:
db.getCollection('Test').find({'color':'red'},{'color':'yellow'});
Assume that color red is present in the one collection and yellow is present in another collection, but I am getting the response only from the first query.
Expectation:
1.If both the queries are present in any of the collection I should get both
responses.
2.If anyone of the query is invalid or element is not present in the collection,
I should not get any response.
Thanks in advance
Since you want to match existence of both values, use $all operator:
db.getCollection('Test').find({color:{$all:["red","yellow"]}})
Edit
I managed to get your output, but I think this could be simplified. I thought about different options and ended up in this query:
db.colors.aggregate([{
$facet:{
cond1:[{$match:{color:"red"}}],
cond2:[{$match:{color:"yellow"}}]
}},
{$project:{match1: "$cond1", match2:"$cond2" ,size1:{$size: "$cond1"},
size2:{$size: "$cond2"}}},
{$project:{result:{$cond:[{$and:[{$gte:["$size1",1]},{$gte:
["$size2",1]}]},{$concatArrays:["$match1","$match2"]},[]]}}}
])
I think there is something wrong with your question.
I think you are looking for something like this db.getCollection('Test').find({color: {$in: ['red','yellow']}});
I hope this will help.

Using cursor in my mongodb database, need guidance on fixing my queries

So right now I want to use cursor to find all restaurants which are good for groups, have a price range less than or equal to three and have more than 50 reviews that have reviews with at least 5 "useful" votes;
db.business.find({$and:[{"attributes": /.*GoodForGroups: True.*/i},{review_count:{$gte:50}},{"attributes.RestaurantsPriceRange2":{$lte:3}}]})
But so far this query turn up nothing, so is there anything wrong with it?
Also this is what I can think of for my cursor so far, feel free to change it if you see anything wrong with it.
var myCursor=db.business.find({$and:[{"attributes": /.GoodForGroups: True./i},{review_count:{$gte:50}},{"attributes.RestaurantsPriceRange2":{$lte:3}}]},{business_id:true, _id: false})
while(myCursor.hasNext()){
db.reviews.find({$and:[{business_id:myCursor.next().business_id},{"useful":{$gte: 5}}]});
}
Firstly, you don't need the $and in your query, mongodb by default perform a $and.
Secondly, you are trying to query keys of your document, it is not possible.
Thirdly, your GoodForGroups should have a boolean value. You don't need a regex here.
Please run:
db.business.find({"attributes.GoodForGroups": true},{review_count:{$gte:50}},{"attributes.RestaurantsPriceRange2":{$lte:3}})

How do I make a mongo query for something that is not in a subdocument array of heterodox size?

I have a mongodb collection full of 65k+ documents, each one with a properties named site_histories. The value of it is an array that might be empty, or might not be. If it is not empty, it will have one or more objects similar to this:
"site_histories" : "[{\"site_id\":\"129373\",\"accepted\":\"1\",\"rejected\":\"0\",\"pending\":\"0\",\"user_id\":\"12743\"}]"
I need to make a query that will look for every instance in the collection of a document that does not have a given user_id.
I'm pretty new to Mongo, so I was trying to make a query that would find every instance that does have the given user_id, which I was then planning on adding a "$ne" to, but even that didn't work. This is the query I was using that didn't work:
db.test.find({site_histories: { $elemMatch: {user_id: '12743\' }}})
So can anyone tell me why this query didn't work? And can anyone help me format a query that will do what I need the final query to do?
If your site_histories really is an array, it should be as simple as doing:
db.test.find({"site_histories.user_id": "12743"})
That looks in all the elements of the array.
However, I'm a bit scared of all those backslashes. If site_histories is a string, that won't work. It would mean that the schema is poorly designed, you'd maybe try with $regex