How can Mongo query specify that two conditions in an array are satisfied at the same time? - mongodb

For example, the doc is
{'id':'1',
'tag':[{'tag_a':'A',
'score':'10'},
{'tag_b':'B',
'score':'0'}
]
}
I want get the doc that satisfied tag_b get 10 points in my collection. Obviously, I should not get this doc. However, when I use the query below
{$and:[{'tag.tag_b':'B','tag.score':'10'}]}
This doc will appear in the results.
How can I avoid this situation. Thanks!

Related

How to use mongodb change stream instead of periodic query?

I wan't to calculate sum the documents in my collection satisfying a query. I dont want to poll my collection. How can you do this with mongodb changestream?
For example there are documents in the database and they all have some property: {"destination": "Target1"} And i want to know the amount of documents which are satisfying this previous requirement.
I don't want to run a query on every change of a collection. Because the documents changing very often
I am looking for a similar to oracle's cqn
You can use changestream and watch changes as follow:
watchCursor = db.getSiblingDB("mydatabase").mycollection.watch()
while (!watchCursor.isExhausted()){
if (watchCursor.hasNext()){
printjson(watchCursor.next());
}
}
changeStream docs
But perhaps you may do some query and use some good indexes?
It seems you can just execute:
db.collection.count({destination:"Target1"})
and if you have index on "destination" field it will be pretty quick ...

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.

Mongo intersection measure select

I have the following documents:
{'variations': ['BlueViolet', 'CadetBlue', 'Cyan']}
{'variations': ['LightPink', 'VioletRed']}
And I want to write a query that selects all documents where size of intersection between variations field and {'Cyan', 'CadetBlue', 'SmoothsRed'} is greater than 2.
Can this be performed with mongodb operators?
This link explains how to achieve what you want - https://docs.mongodb.com/manual/reference/operator/aggregation/setIntersection/
In order to write the comparison, I'll have to assume each document can be uniquely identified using an _id value, and then you can write your query using the solution given in this answer - How to find set intersection of sets between the documents in a single collection in MongoDB?
Good luck

Mongo DB search based on multiple conditions

I am trying to search based on multiple conditions which works but the problem is that does not behave like this.
Assuming i have a search query like
Orders.find({$or: {"status":{"$in":["open", "closed"]},"paymentStatus":{"$in":["unpaid"]}}}
)
and i add another filter parameter like approvalStatus it does not leave the previously found items but rather it treats the query like an AND that will return an empty collection of items if one of the queries does not match.
How can i write a query that regardless of what is passed into it, it will retain previously found items even if there is no record in one of the conditions.
like a simple OR query in sql
I hope i explained this well enough
Using $or here is the right approach, but its value needs to be an array of query expressions, not an object.
So your query should look something like this instead:
Orders.find({$or: [
{"status": {"$in": ["open", "closed"]}},
{"paymentStatus": {"$in": ["unpaid"]}},
{"approvalStatus": {"$in": ["approved"]}}
]})

Mongo Get Count While Returning Whole Documents and Should Queries

I am new to Mongo and can't seem to figure out the following after reading posts and the documentation. I am executing the following query:
db.collection.find({'name':'example name'})
Which returns 14 results. I can get the count of correctly by executing:
db.collection.find({'name':'example name'}).count()
However, I want to return the full documents and the count in a single query, similar to the way Elasticsearch does. Is there anyway to do this.
Additionally, is there any equivalence to Elasticsearch's Bool should query (http://www.elasticsearch.org/guide/en/elasticsearch/reference/current/query-dsl-bool-query.html). Essentially I would want to rank the results, so that those with attribute 'onSale=True' are returned before 'onSale=False'.
I'm not sure about your second question, whether MongoDB provides some mechanism equivalent to Elasticsearch's Bool should query.
But for your 1st question, I think you can use Cursor.
var cursor = db.collection.find({'name':'example name'});
Once you've got the cursor, you can use it for getting the count in the following way:
cursor.count()
as well as for getting the documents wrapped in an array in the following way:
cursor.toArray()
For more info on cursor, please see the below mentioned link:
http://docs.mongodb.org/manual/tutorial/iterate-a-cursor/