how to get all data with special condition on mongodb - mongodb

How to get all data with condition discountPrice not nil?
if i have object like this inside my mongo db :
when i'm execute this query "db.products.find()", i get result like below :
{
"_id" : ObjectId("123456778"),
"items" : [
{
"discountPrice" : 159200,
"_id" : ObjectId("54697e689857572459444162"),
}
]
},
{
"_id" : ObjectId("847446468"),
"items" : [
{
"discountPrice" : nil,
"_id" : ObjectId("54697e689857572459444162"),
}
]
}
how to get result like this :
{
"_id" : ObjectId("123456778"),
"items" : [
{
"discountPrice" : 159200,
"_id" : ObjectId("54697e689857572459444162"),
}
]
}
how do that?

You can use the $ne operator to match values that are "not equal" to null:
db.products.find( { "items.discountprice": { "$ne": null } } )
I've changed your reference of nil to null because nil is not a valid BSON type. I'm assuming that you are using ruby which uses nil in favor of null. Using your mongodb drivers, I think you'll still be able to actually supply the value nil, but in this language agnostic post the correct value would be null.

You can do it like this:
db.products.find({'items.discountPrice':{ '$ne': null }});
more info on queries can be found here : http://docs.mongodb.org/manual/reference/operator/query/exists/
Edit: updated example with using null.

Related

How to search document with condition of not having exact object in array of objects?

I have a collection of persons whose schema looks like the collection of following documents.
Document: {
name:
age:
educations:[{
title:xyz,
passed_year:2005,
univercity:abc},
{
title:asd
passed_year:2007,
univercity:mno
}],
current_city:ghi
}
Now I wanna show all the persons who has not done xyz education from abc university in year 2005.
I think two possible queries for this need but not sure which one to use as both of them are giving me the output
Query 1:
db.persons.find({"education":{$ne:{$elemMatch:{"title":"xyz","passed_year":2005,"univercity":"abc"}}}})
Query 2:
db.persons.find({"education":{$not:{$elemMatch:{"title":"xyz","passed_year":2005,"univercity":"abc"}}}})
I'm quite confused about operator $ne and $not, which one should I use with $elemMatch as both of them are giving me the output.
Given this $elemMatch: {"title":"xyz","passed_year":2005,"univercity":"abc"} I think you want to exclude any documents which contain an sub document in the educations array which contains all of these pairs:
"title" : "xyz"
"passed_year" : 2005
"univercity" : "abc"
This query will achieve that:
db.persons.find({
"educations": {
$not: {
$elemMatch:{"title": "xyz", "passed_year": 2005, "univercity": "abc"}
}
}
})
In your question you wrote:
both of them are giving me the output
I suspect this is because your query is specifying education whereas the correct attribute name is educations. By specifying education you are adding a predicate which cannot be evaluated since it references a non existent document attribute so regardless of whether that predicate uses $ne or $not it will simply not be applied.
In answer to the question of which operator to use: $not or $ne: if you run the above query with .explain(true) you'll notice that the parsed query produced by Mongo is very different for each of these operators.
Using $ne
"parsedQuery" : {
"$not" : {
"educations" : {
"$eq" : {
"$elemMatch" : {
"title" : "xyz",
"passed_year" : 2005,
"univercity" : "abc"
}
}
}
}
}
Using $not:
"parsedQuery" : {
"$not" : {
"educations" : {
"$elemMatch" : {
"$and" : [
{
"passed_year" : {
"$eq" : 2005
}
},
{
"title" : {
"$eq" : "xyz"
}
},
{
"univercity" : {
"$eq" : "abc"
}
}
]
}
}
}
}
So, it looks like use of $ne causes Mongo to do something like this psuedo code ...
not educations equalTo "$elemMatch" : {"title" : "xyz", "passed_year" : 2005, "univercity" : "abc"}
... i.e. it treats the elemMatch clause as if it is the RHS of an equality operation whereas use of $not causes Mongo to actually evaluate the elemMatch clause.

Positional operator and field limitation

In a find query projection, fields I specify after the positional operator are ignored and the whole document is always returned.
'myArray.$.myField' : 1 behave exactly like 'myArray.$' : 1
the positional operator selects the right document. But this document is quite big. I would like to project only 1 field from it.
Exemple:
db.getCollection('match').find({"participantsData.id" : 0001}, { 'participantsData.$.id': 1, })
here the response I have
{
"_id" : "myid",
"matchCreation" : 1463916465614,
"participantsData" : [
{
"id" : 0001,
"plenty" : "of",
"other" : "fields",
"and" : "subdocuments..."
}
]
}
This is what I want
{
"_id" : "myid",
"matchCreation" : 1463916465614,
"participantsData" : [
{
"id" : 0001
}
]
}
Is it possible with mongo?
Yes it can be done in mongo
Please try the below query
db.getCollection('match').find(
{"participantsData.id" : 0001},
{"participantsData.id": 1, "matchCreation": 1 })
This will give you the below result
{
"_id" : "myid",
"matchCreation" : 1463916465614,
"participantsData" : [
{
"id" : 1
}
]
}

MongoDB filter array element in a nested object

I have a document as follows:
{
"_id" : ObjectId("56423b2558cb340599108b35"),
"test" : {
"source" : [
{
"member" : "abc"
},
{
"member" : "xyz"
}
]
}
}
I want to filter on the array element xyz, and I am trying the following query:
db.coll.find({ "test.source.member" : "xyz" }, { "test.source.$.member" : true }).pretty()
Apparently it used to work on 2.4, on 2.6 it does not work,
On 2.4 it returned the "xyz", whereas on 2.6 it returns "abc" i.e. the first element. Is there a way to filter "abc" because eventually i want to update. BTW, i also tried with $elemMatch and it seems to give the same output "abc".
Thanks.
According to the Docs, if you are running 2.6, this should give you the correct output:
db.coll.find({ "test.source.member" : "xyz"}, { "test.source.$" : 1}).pretty()
You could extract the member by doing this:
var member = db.coll.find(
{ "test.source.member" : "xyz"},
{ "test.source.$" : 1}
).test.source[0].member;
The value of member would be:
xyz

MongoDb - Query for specific subdocument

I have a set of mongodb documents with the following structure:
{
"_id" : NUUID("58fbb893-dfe9-4f08-a761-5629d889647d"),
"Identifiers" : {
"IdentificationLevel" : 2,
"Identifier" : "extranet\\test#test.com"
},
"Personal" : {
"FirstName" : "Test",
"Surname" : "Test"
},
"Tags" : {
"Entries" : {
"ContactLists" : {
"Values" : {
"0" : {
"Value" : "{292D8695-4936-4865-A413-800960626E6D}",
"DateTime" : ISODate("2015-04-30T09:14:45.549Z")
}
}
}
}
}
}
How can I make a query with the mongo shell which finds all documents with a specific "Value" (e.g.{292D8695-4936-4865-A413-800960626E6D} in the Tag.Entries.ContactLists.Values path?
The structure is unfortunately locked by Sitecore, so it is not an options to use another structure.
As your sample collection structure show Values is object, it contains only one Value. Also you must check for Value as it contains extra paranthesis. If you want to get Value from given structure try following query :
db.collection.find({
"Tags.Entries.ContactLists.Values.0.Value": "{292D8695-4936-4865-A413-800960626E6D}"
})

How to return specific field's value in mongodb

how can I return a specific value for a specific document in MongoDB? For example, I have a schema that looks like:
{
"_id" : "XfCZSje7GjynvMZu7",
"createdAt" : ISODate("2015-03-23T14:52:44.084Z"),
"services" : {
"password" : {
"bcrypt" : "$2a$10$tcb01VbDMVhH03mbRdKYL.79FPj/fFMP62BDpcvpoTfF3LPgjHJoq"
},
"resume" : {
"loginTokens" : [ ]
}
},
"emails" : {
"address" : "abc123#gmu.edu",
"verified" : true
},
"profile" : {
"companyName" : "comp1",
"flagged" : true,
"phoneNum" : "7778883333"
}}
I want to return and store the value for profile.flagged specifically for the document with _id : XfCZSje7GjynvMZu7. So far I have tried:
db.users.find({_id:'myfi3E4YTf9z6tdgS'},{admin:1})
and
db.users.find({_id: 'myfi3E4YTf9z6tdgS'}, {profile:admin});
I want the query to return true or false depending on the assigned value.
Can someone help? Thanks!
MongoDB queries always return document objects, not single values. So one way to do this is with shell code like:
var flagged =
db.users.findOne({_id: 'myfi3E4YTf9z6tdgS'}, {'profile.flagged': 1}).profile.flagged;
Note the use of findOne instead of find so that you're working with just a single doc instead of the cursor that you get with find.
The correct answer here is the method .distinct() (link here)
Use it like this:
db.users.find({_id:'myfi3E4YTf9z6tdgS'},{admin:1}).distinct('admin')
The result will be: 1 or 0