How to count all occurrences of an element in MongoDB? - mongodb

Let's say I have the following entries in my MongoDB.
{ "_id" : ObjectId("5474af69d4b28042fb63b81b"), "name" : "a", "time" : NumberLong("1412774562000"), "location" : "DE" }
{ "_id" : ObjectId("5474af69d4b28042fb63b81c"), "name" : "b", "time" : NumberLong("1412774562020"), "location" : "DE" }
{ "_id" : ObjectId("5474af69d4b28042fb63b81d"), "name" : "c", "time" : NumberLong("1412774562040"), "location" : "US" }
{ "_id" : ObjectId("5474af69d4b28042fb63b81e"), "name" : "d", "time" : NumberLong("1412774562060"), "location" : "AU" }
{ "_id" : ObjectId("5474af69d4b28042fb63b81f"), "name" : "e", "time" : NumberLong("1412774562080"), "location" : "CN" }
As a result, I need to know how often each specific "location" can be found in the database e.g.
{"DE": "2",
"US": "1",
"AU": "1",
"CN": "1"}
I have no information about all the different locations in the database so querying after a known location for example
db.c.find({"location": "DE"})
would not solve my problem.

You need to make use of the aggregation pipeline with a group and project stage operators.
db.c.aggregate([
{$group:{"_id":"$location","count":{$sum:1}}},
{$project:{"location":"$_id","occurance":"$count"}}
])

Related

MongoDB : Push data to a map

I have employee json as below in db, I want to create a map of "addressId"(key) and "city"(value) and return the result.
{
"_id" :1,
"_class" : "com.entity.Employee",
"clientId" : 1,
"addresses" : [
{
"addressId" : 1,
"street" : "ghi",
"city" : "Hyderabad"
},
{
"addressId" : 2,
"street" : "abc",
"city" : "Bangalore"
},
{
"addressId" : 3,
"street" : "def",
"city" : "Chennai"
}
]
}
Please suggest me which operator can I use and whether this can be achieved using $project.
Yes you have to use projection with unwind and forEach to make key value pair
try below mongo query
db.collection_name.aggregate([{"$unwind":"$addresses"},{"$project": {"addressId": "$addresses.addressId", "city":"$addresses.city", "_class":"$_class","clientId":"$clientId"} }]).forEach(function(ojb){ojb[ojb.addressId]=ojb.city; printjson(ojb);});

Mongodb : How to select objects where an array contains only a specific field?

I have two objects :
{
"_id" : ObjectId("54be5f5528c13bfc3409e8c2"),
"name" : "Antonio",
"lastname" : "de Cabezón",
"by" : 1510,
"dy" : 1566,
"country" : "spain",
"genre" : [
"classical",
"baroque"
]
}
{
"_id" : ObjectId("54be5f5528c13bfc3409e8c1"),
"name" : "Guillaume-Antoine",
"lastname" : "Calvière",
"by" : 1695,
"dy" : 1755,
"country" : "france",
"genre" : [
"baroque"
]
}
When i do a db.currentdb.find({genre: 'baroque'}), it returns me the first object too.
I'd like to fetch only the object where the genre is only "baroque". What would be the proper way to do it ?
You could try
db.currentdb.find({genre: ['baroque']})
Also, take a look to the documentation:
https://docs.mongodb.org/manual/reference/method/db.collection.find/

Get document based on multiple criteria of embedded collection

I have the following document, I need to search for multiple items from the embedded collection"items".
Here's an example of a single SKU
db.sku.findOne()
{
"_id" : NumberLong(1192),
"description" : "Uploaded via CSV",
"items" : [
{
"_id" : NumberLong(2),
"category" : DBRef("category", NumberLong(1)),
"description" : "840 tag visual",
"name" : "840 Visual Mini Round",
"version" : NumberLong(0)
},
{
"_id" : NumberLong(7),
"category" : DBRef("category", NumberLong(2)),
"description" : "Maxi",
"name" : "Maxi",
"version" : NumberLong(0)
},
{
"_id" : NumberLong(11),
"category" : DBRef("category", NumberLong(3)),
"description" : "Button",
"name" : "Button",
"version" : NumberLong(0)
},
{
"_id" : NumberLong(16),
"category" : DBRef("category", NumberLong(4)),
"customizationFields" : [
{
"_class" : "CustomizationField",
"_id" : NumberLong(1),
"displayText" : "Custom Print 1",
"fieldName" : "customPrint1",
"listOrder" : 1,
"maxInputLength" : 12,
"required" : false,
"version" : NumberLong(0)
},
{
"_class" : "CustomizationField",
"_id" : NumberLong(2),
"displayText" : "Custom Print 2",
"fieldName" : "customPrint2",
"listOrder" : 2,
"maxInputLength" : 17,
"required" : false,
"version" : NumberLong(0)
}
],
"description" : "2 custom lines of farm print",
"name" : "Custom 2",
"version" : NumberLong(2)
},
{
"_id" : NumberLong(20),
"category" : DBRef("category", NumberLong(5)),
"description" : "Color Red",
"name" : "Red",
"version" : NumberLong(0)
}
],
"skuCode" : "NF-USDA-XC2/SM-BC-R",
"version" : 0,
"webCowOptions" : "840miniwithcust2"
}
There are repeat items.id throughout the embedded collection. Each Sku is made up of multiple items, all combinations are unique, but one item will be part of many Skus.
I'm struggling with the query structure to get what I'm looking for.
Here are a few things I have tried:
db.sku.find({'items._id':2},{'items._id':7})
That one only returns items with the id of 7
db.sku.find({items:{$all:[{_id:5}]}})
That one doesn't return anything, but it came up when looking for solutions. I found about it in the MongoDB manual
Here's an example of a expected result:
sku:{ "_id" : NumberLong(1013),
"items" : [ { "_id" : NumberLong(5) },
{ "_id" : NumberLong(7) },
{ "_id" : NumberLong(12) },
{ "_id" : NumberLong(16) },
{ "_id" :NumberLong(2) } ] },
sku:
{ "_id" : NumberLong(1014),
"items" : [ { "_id" : NumberLong(5) },
{ "_id" : NumberLong(7) },
{ "_id" : NumberLong(2) },
{ "_id" : NumberLong(16) },
{ "_id" :NumberLong(24) } ] },
sku:
{ "_id" : NumberLong(1015),
"items" : [ { "_id" : NumberLong(5) },
{ "_id" : NumberLong(7) },
{ "_id" : NumberLong(12) },
{ "_id" : NumberLong(2) },
{ "_id" :NumberLong(5) } ] }
Each Sku that comes back has both a item of id:7, and id:2, with any other items they have.
To further clarify, my purpose is to determine how many remaining combinations exist after entering the first couple of items.
Basically a customer will start specifying items, and we'll weed it down to the remaining valid combinations. So Sku.items[0].id=5 can only be combined with items[1].id=7 or items[1].id=10 …. Then items[1].id=7 can only be combined with items[2].id=20 … and so forth
The goal was to simplify my rules for purchase, and drive it all from the Sku codes. I don't know if I dug a deeper hole instead.
Thank you,
On the part of extracting the sku with item IDs 2 and 7, when I recall correctly, you have to use $elemMatch:
db.sku.find({'items' :{ '$all' :[{ '$elemMatch':{ '_id' : 2 }},{'$elemMatch': { '_id' : 7 }}]}} )
which selects all sku where there is each an item with _id 2 and 7.
You can use aggregation pipelines
db.sku.aggregate([
{"$unwind": "$sku.items"},
{"$group": {"_id": "$_id", "items": {"$addToSet":{"_id": "$items._id"}}}},
{"$match": {"items._id": {$all:[2,7]}}}
])

mongodb: how to add a new property for mongo's geolocation function

I have a collection of events in mongodb, and below is on sample of the document in the collection:
{
"id" : 15178390976,
"title" : "Basics of Writing a Business Plan (Essex Office)",
"end_date" : "2015-03-18 11:00:00",
"venue" :
{
"city" : "Essex",
"name" : "WindsorEssex Small Business Centre (Essex Office)",
"country" : "Canada",
"region" : "Ontario",
"longitude" : -82.823545,
"postal_code" : "N8M 2J3",
"address" : "39 Maidstone Avenue East",
"latitude" : 42.17792,
"id" : 8864285,
"Lat-Long" : "42.17792 / -82.823545"
}
}
I want to modify the collection of documents, so that I can apply the geospatial spherical function in MongoDB. I want to modify all the documents in the collection as follows:
{
"id" : 15178390976,
"title" : "Basics of Writing a Business Plan (Essex Office)",
"end_date" : "2015-03-18 11:00:00",
"venue" :
{
"city" : "Essex",
"name" : "WindsorEssex Small Business Centre (Essex Office)",
"country" : "Canada",
"region" : "Ontario",
"longitude" : -82.823545,
"postal_code" : "N8M 2J3",
"address" : "39 Maidstone Avenue East",
"latitude" : 42.17792,
"id" : 8864285,
"Lat-Long" : "42.17792 / -82.823545"
},
location:
{
"type":"Point",
"coordinates":[-82.823545, 42.17792]
}
}
the value in the coordinates are from venue.longitude and venue.latitude.
How can I update the documents to what I want? I have tried $update and $projection in aggregation, none of them are working for the location.coordinates property. I failed to push the values into the array.
the aggregation I use is:
db.coll.aggregation([
{ $project:
{
"id": "$id",
"title":"$title",
"venue":"$venue",
"location.type": "Point",
"location.coordinate":["$venue.longitude","$venue.latitude"]
}
},
{ $out:newoutput }
])
Anyone can please help me?

MongoTemplate find not returning results

MongoTemplate not returning results.
Json:
{
"_id" : ObjectId("51acf6ab0d5d46077ae12b2a"),
"docType" : "row",
"value" : {
"entity" : {
"#id" : "1111",
"#version" : "3434",
"name" : "XY XY",
"listId" : 28,
"listCode" : "BS",
"entityType" : "03",
"createdDate" : "09/12/2006",
"lastUpdateDate" : "04/20/2011",
"source" : "CCC",
"address1" : "XXXXXXXX",
"city" : "CITY",
"country" : "CO",
"countryName" : "COUNTRY NAME"
}
},
"createdDate" : ISODate("2013-06-03T20:03:55.127Z"),
"createdBy" : "Test"
}
Query:
queryy = new Query(Criteria.where("docType").is("row").andOperator(Criteria.where("value.entity.city").is("CITY")));
Above query doesn't return any result back.
Am I missing something? Please help.
Try this:
query = new Query(Criteria.where("docType").is("row")
.and("value.entity.city").is("CITY"));
You're code doesn't need the andOperator function (as that translates to $and). It just needs multiple criteria using and.
And, you can use query.toString() to see what the output would be of the query (and compare it to what you might have used in the MongoDB shell.