MongoDB query to compute percentage - mongodb

I am new to MongoDB and kind of stuck at this query. Any help/guidance will be highly appreciated. I am not able to calculate the percentage in the desired way. There is something wrong with my pipeline where prerequisites of percentage are not computed correctly. Following I provide my unsuccessful attempt along with the desired output.
Single entry in the collection looks like below:
_id : ObjectId("602fb382f060fff5419fd0d1")
time : "2019/05/02 00:00:00"
station_id : 3544
station_name : "Underhill Ave &; Pacific St"
station_status : "In Service"
latitude : 40.6804836
longitude : -73.9646795
zipcode : 11238
borough : "Brooklyn"
neighbourhood : "Prospect Heights"
available_bikes : 5
available_docks : 21
The query I am trying to solve is:
Given a station_id (e.g., 522) and a num_hours (e.g., 3) passed as parameters:
- Consider only the measurements where the station_status = “In Service”.
- Consider only the measurements for that concrete
“station_id”.
- Compute the percentage of measurements with
available_bikes = 0 for each hour of the day (e.g., for the period
[8am, 9am) the percentage is 15.06% and for the period [9am, 10am)
the percentage is
27.32%).
- Sort the percentage results in decreasing order.
- Return the top “num_hours” documents.
The desired output is:
--- DOCUMENT 0 INFO ---
---------------------------------
hour : 19
percentage : 65.37
total_measurements : 283
zero_bikes_measurements : 185
---------------------------------
--- DOCUMENT 1 INFO ---
---------------------------------
hour : 21
percentage : 64.79
total_measurements : 284
zero_bikes_measurements : 184
---------------------------------
--- DOCUMENT 2 INFO ---
---------------------------------
hour : 00
percentage : 63.73
total_measurements : 284
zero_bikes_measurements : 181
My attempt is:
command_1 = {"$match": {"station_status": "In Service", "station_id": station_id, "available_bikes": 0}}
my_query.append(command_1)
command_2 = {"$group": {"_id": "null", "total_measurements": {"$sum": 1}}}
my_query.append(command_2)
command_3 = {"$project": {"_id": 0,
"station_id": 1,
"station_status": 1,
"hour": {"$substr": ["$time", 11, 2]},
"available_bikes": 1,
"total_measurements": {"$sum": 1}
}
}
my_query.append(command_3)
command_4 = {"$group": {"_id": "$hour", "zero_bikes_measurements": {"$sum": 1}}}
my_query.append(command_4)
command_5 = {"$project": {"percent": {
"$multiply": [{"$divide": ["$total_measurements", "$zero_bikes_measurements"]},
100]}}}
my_query.append(command_5)

I've taken a look at this and I'm going to offer some sincere advice:
Don't try and do this in an aggregate query. Just go back to basics and pull the numbers out using find()s and then calculate the numbers in python.
If you want to persist with an aggregate query, I will say that your match command filters on available_bikes equal to zero. You never have the total number of measurements, so you can never find the percentage. Also when you have done your first $group, your "lose" your projection so at that point in the pipeline you only have total_measurements and that's it (comment out the commands 3 to 5 to see what I mean).

Related

Count no.of elements in an array and sum for every document of a collection in mongodb?

I need to count to number of all the products from all the orders and also number of products per individual order ?
data in my collection ( order_fact) :
{"orderid":"c3e15faf-e338-4ed5-9bbb-bbcd15295fd7","Id_cust":"10995116278711","Id_date":"91","TotalPrice":1933.53,"Orderline":[{"productId":"4165","asin":"B005G2G2SQ","title":"ESEE-6 Plain Black Blade With Grey Removable Lined Micarta Handles 1095 Carbon Steel 57-Rc","price":140.05,"brand":"Fila_(company)"},{"productId":"5916","asin":"B001CJ2LQ4","title":"Aimpoint M4s 2 Minute of Angle QRP2 CompM4 Sight with Mount","price":804.95,"brand":"Atletica"},{"productId":"7779","asin":"B003DO5L3G","title":"Lee Precision Load Master 223 Remington Reloading Rifle Kit (Red)","price":249.26,"brand":"BURRDA"},{"productId":"2722","asin":"B0017U1MJU","title":"Casio Mens PAW1500-1V Pathfinder Multi-Band Solar Atomic Ultimate Watch","price":190.27,"brand":"Reebok"},{"productId":"52","asin":"B007SYGLZO","title":"Armasight Spark CORE Multi-Purpose Night Vision Monocular","price":549.0,"brand":"Signia_(sportswear)"}],"Livreur":{"Id_livreur":"91bcee9f-8896-4e18-a24c-a8e86b97b3a1","Nom":"Tyson Anderson","gender":"Male","phone":"7-458-665-3444"}},
{"orderid":"35b26e6d-e450-4edc-9071-306cea10a083","Id_cust":"10995116278711","Id_date":"249","TotalPrice":1540.91,"Orderline":[{"productId":"1978","asin":"B001CZBMRC","title":"Benchmade Osborne Design Rift Knife","price":178.5,"brand":"CCM_(ice_hockey)"},{"productId":"857","asin":"B004IIKA2I","title":"Barnett Quad 400 Crossbow Package (Quiver 3 - 22-Inch Arrows and 4x32mm Scope)","price":354.99,"brand":"Fischer_(company)"},{"productId":"8362","asin":"B00635GTTW","title":"Schwinn IC2 Indoor Cycling Exercise Bike","price":422.49,"brand":"Admiral_Sportswear"},{"productId":"216","asin":"B000GKN45C","title":"Swagman XTC-4 Cross-Country 4-Bike Hitch Mount Rack (2-Inch Receiver Hitch)","price":349.99,"brand":"Elfin_Sports_Cars"},{"productId":"7766","asin":"B000KKEPJ2","title":"Lyman Reloading Press T-Mag Turret Press","price":234.94,"brand":"BURRDA"}],"Livreur":{"Id_livreur":"48d64c09-7a63-4fca-815a-a96921a82ee7","Nom":"Abdul Coll","gender":"Male","phone":"1-273-204-4721"}},
{"orderid":"ffaec62e-9875-42af-8789-0a97eabe77e4","Id_cust":"10995116278711","Id_date":"67","TotalPrice":1058.41,"Orderline":[{"productId":"2675","asin":"B00BPRM2O4","title":"Large Exercise Mat Large Workout Mat With A Unique Fabric Finish That Provides Excellent Traction And Floor Protection. Can Be Used In Conjunction With The Square36 YOGA Mat. The Square36 CARDIO Mat - The BIG Exercise Mat- Step Into the Square.","price":159.99,"brand":"Reebok"},{"productId":"1380","asin":"B000EQCVQ6","title":"Eureka! Apex 2XT Two-Person Tent","price":175.16,"brand":"Topper_(sports)"},{"productId":"9665","asin":"B004H4VSI8","title":"IRONMAN HIGH CAPACITY GRAVITY 3000 INVERSION TABLE","price":239.8,"brand":"Wilson_Sporting_Goods"},{"productId":"7603","asin":"B0017SC9H6","title":"Zero Tolerance Combat Folding Knife","price":199.0,"brand":"Tramontana_(sports_car)"},{"productId":"887","asin":"B00BCLL8C0","title":"SportRack SR7018 Vista XL Rear Opening Cargo Box 18-Cubic Feet","price":284.46,"brand":"Fischer_(company)"}],"Livreur":{"Id_livreur":"7548ac7b-5bf7-4c5a-a80d-5390b73b9b90","Nom":"Henry Wilde","gender":"Male","phone":"3-624-033-5243"}},
{"orderid":"125e7887-c41d-4a5a-aa6b-d2a3679d58e7","Id_cust":"10995116278711","Id_date":"477","TotalPrice":1624.98,"Orderline":[{"productId":"6250","asin":"B005DYQ9V2","title":"Invicta Men s 1463 Reserve Collection Chronograph Silver Dial Stainless Steel Watch","price":199.95,"brand":"Keuka_(brand)"},{"productId":"1138","asin":"B000AMRN12","title":"Stamina AeroPilates Reformer with Free-Form Cardio Rebounder","price":449.0,"brand":"Topper_(sports)"},{"productId":"7575","asin":"B005D7FXMA","title":"Cygolite Expilion 400 Usb Rechargeable Headlight with Quick Release Li-Ion Battery Stick and Wall Charger","price":113.99,"brand":"Derbi"},{"productId":"6529","asin":"B005Z2CYX4","title":"Zero Tolerance ZT0550 Hinderer Design Folding Knife","price":160.0,"brand":"CA_Sports"},{"productId":"7125","asin":"B007INYN6O","title":"Barnett Zombie 350 CRT Crossbow","price":702.04,"brand":"Elan_Snowboards"}],"Livreur":{"Id_livreur":"a1060a87-fdff-4acc-b728-c805b72b0740","Nom":"Percy Thornton","gender":"Male","phone":"5-744-522-0782"}},
{"orderid":"b259eafc-2f47-47dc-927b-5b6d6edbba1d","Id_cust":"10995116278711","Id_date":"617","TotalPrice":1484.76,"Orderline":[{"productId":"7667","asin":"B008W1TUAK","title":"MAGPUL ACS CARB STOCK MIL-SPEC BLACK","price":98.99,"brand":"POC_Sports"},{"productId":"6406","asin":"B001CJX50K","title":"Kinetic Rock n Roll Trainer w/Road Resistance Unit","price":389.99,"brand":"MYLAPS_Sports_Timing"},{"productId":"1883","asin":"B000O8Z7TW","title":"KNEX Education - Exploring Machines","price":126.79,"brand":"TRYMAX"},{"productId":"4158","asin":"B003AQKQAA","title":"Vortex Viper PST 6-24x50 Rifle PST-624S1-M","price":749.0,"brand":"Fila_(company)"},{"productId":"7578","asin":"B00D43A93I","title":"Under Armour Hammer 8600014-4808 Polarized Wrap Sunglasses","price":119.99,"brand":"Derbi"}],"Livreur":{"Id_livreur":"eb135eef-7ee2-4d90-b073-cbd4570935b3","Nom":"Violet Adler","gender":"Female","phone":"5-466-075-2676"}},
{"orderid":"b5755c1e-fc3f-4481-a175-edfc82290ea5","Id_cust":"10995116278711","Id_date":"208","TotalPrice":2487.71,"Orderline":[{"productId":"965","asin":"B000O3AVNY","title":"Advanced Elements AdvancedFrame Expedition Kayak","price":599.99,"brand":"Donnay_(sports)"},{"productId":"6888","asin":"B0029KL3S2","title":"Precor 240i Commercial Series StretchTrainer","price":704.2,"brand":"Elan_(company)"},{"productId":"6439","asin":"B004PJ1J4S","title":"Invicta Men s 6566 Subaqua Noma IV Collection Chronograph Black Polyurethane Watch","price":340.65,"brand":"MYLAPS_Sports_Timing"},{"productId":"9503","asin":"B0034PXYRY","title":"Eotech EXPS3-0 Holographic Weapon Site","price":606.92,"brand":"EA_Sports"},{"productId":"7740","asin":"B00271ERVI","title":"Crimson Trace Lasergrip for Ruger Lcr","price":235.95,"brand":"BURRDA"}],"Livreur":{"Id_livreur":"c75a672e-37cf-498e-8bf9-8dae7857165f","Nom":"Renee Eyres","gender":"Female","phone":"6-311-624-4031"}},
{"orderid":"8a129f4e-e736-4919-9a22-c98373f1df3b","Id_cust":"10995116278711","Id_date":"390","TotalPrice":1233.67,"Orderline":[{"productId":"1929","asin":"B004P4HH8U","title":"Barnett Ghost 350 CRT Crossbow Package (Quiver 3 - 20-Inch Arrows and Illuminated 3x32mm Scope)","price":509.99,"brand":"TRYMAX"},{"productId":"2940","asin":"B004IIZVQ8","title":"Barnett Wildcat C5 Crossbow Package (Quiver 3 - 20-Inch Arrows and Premium Red Dot Sight)","price":342.99,"brand":"Volkl"},{"productId":"3174","asin":"B006U0YZPA","title":"Bushnell X-8 6MP Trail Camera with Night Vision and Field Scan","price":136.94,"brand":"Daei_Sport"},{"productId":"6527","asin":"B003MA1SSI","title":"Sadlak Industries M14 National Match Spring Guide","price":40.75,"brand":"CA_Sports"},{"productId":"1759","asin":"B007L4ZGXE","title":"Zero Tolerance ZT0560 Hinderer Design Black Folding Knife","price":203.0,"brand":"Olympikus"}],"Livreur":{"Id_livreur":"2ccb39c1-5c1a-46d8-b394-fc887bd4cecd","Nom":"Faith Flanders","gender":"Female","phone":"2-586-775-3278"}},
{"orderid":"bb671476-5f67-414a-9b84-77498b05f0bd","Id_cust":"10995116278711","Id_date":"205","TotalPrice":1601.81,"Orderline":[{"productId":"810","asin":"B009K28INA","title":"Schwinn 425 Elliptical Trainer (2013)","price":599.99,"brand":"Fischer_(company)"},{"productId":"6802","asin":"B000WY8ZHO","title":"Luminox Men s Navy Seal ColorMark Watch 3051","price":229.09,"brand":"Onda_(sportswear)"},{"productId":"3178","asin":"B007O5B0LC","title":"Weslo Cadence G 5.9 Treadmill","price":351.0,"brand":"Daei_Sport"},{"productId":"2126","asin":"B0025YCYK8","title":"Spyderco Temperence 2 Canvas Micarta Plain Edge Knife","price":207.72,"brand":"Li-Ning"},{"productId":"6736","asin":"B002QWB8HY","title":"CamelBak BFM 3L Backpack","price":214.01,"brand":"Onda_(sportswear)"}],"Livreur":{"Id_livreur":"629b2edd-8bd4-4d50-8e63-33f4904ffd2c","Nom":"Stephanie Garcia","gender":"Female","phone":"6-618-288-6820"}},
{"orderid":"d3016947-f478-4782-941d-37132482a10a","Id_cust":"10995116278711","Id_date":"694","TotalPrice":1534.78,"Orderline":[{"productId":"3029","asin":"B00AJK9CW8","title":"Seiko Men s SRP307 Classic Automatic Dive Watch","price":192.87,"brand":"Kettler"},{"productId":"2964","asin":"B004V956P0","title":"Crosman Optimus Break Barrel Air Rifle (.177)","price":91.98,"brand":"Volkl"},{"productId":"4115","asin":"B003UNZHNY","title":"Schwinn A10 Upright Exercise Bike (2011)","price":199.99,"brand":"Fila_(company)"},{"productId":"6853","asin":"B0081MPIBA","title":"ETEK4 - Planet Eclipse Etek 4 LT / AM Paintball Guns","price":499.95,"brand":"Elan_(company)"},{"productId":"893","asin":"B001AS697O","title":"Bowflex PR1000 Home Gym","price":549.99,"brand":"Fischer_(company)"}],"Livreur":{"Id_livreur":"787192a7-8417-44a9-a5bb-dd9060afd524","Nom":"Isla Denton","gender":"Female","phone":"1-260-416-8800"}},
{"orderid":"30dd4a79-4dac-4043-8fbc-e746e78aced3","Id_cust":"10995116278711","Id_date":"702","TotalPrice":1329.04,"Orderline":[{"productId":"2726","asin":"B005SSWKMK","title":"Casio Men s PRW2500T-7CR Pathfinder Triple Sensor Tough Solar Digital Multi-Function Titanium Pathfinder Casual Watch","price":266.12,"brand":"Reebok"},{"productId":"6563","asin":"B0014NDXGA","title":"Bushnell Tour V2 Standard Edition Golf Laser Rangefinder","price":290.06,"brand":"Onda_(sportswear)"},{"productId":"4856","asin":"B001QD48GC","title":"FreeForm Hideaway Home Gym","price":641.93,"brand":"ASICS"},{"productId":"7653","asin":"B007ZNUG9K","title":"Blackhawk Black TraverseTrack Bipod - 10 - BH71BP10BK","price":50.98,"brand":"POC_Sports"},{"productId":"4166","asin":"B00AJT98OQ","title":"Universal Brass Catcher","price":79.95,"brand":"Fila_(company)"}],"Livreur":{"Id_livreur":"5acb6f8a-fb71-4b32-b40d-fde782d70600","Nom":"Belinda Marshall","gender":"Female","phone":"6-671-643-4273"}},
I need two queries, the first :
Number of all the products from all the orders
the second query :
Number of all the products from per order
You can have something like this :
For First Question :
db.getCollection('order_fact').aggregate([{
$group: {
_id: '',
allProductsFromAllOrdersCount: { $sum: { $cond: { if: { $isArray: "$Orderline" }, then: { $size: "$Orderline" }, else: "NA"} } }
}
}, {
$project: {
_id: 0,
allProductsFromAllOrdersCount: 1
}
}])
For Second Question :
If OrderLine is Array for sure :
db.getCollection('order_fact').aggregate([{$project : {orderid:1 ,OrderLine : 1, totalNoOfProducts : { $size: "$Orderline"}}}])
else with conditional statements:
db.getCollection('order_fact').aggregate([{$project : {orderid:1 ,OrderLine : 1, totalNoOfProducts : { $cond: { if: { $isArray: "$Orderline" }, then: { $size: "$Orderline" }, else: "NA"} }}}])
If you need the count along with original document to be returned :
db.getCollection('order_fact').aggregate([{$addFields: {totalNoOfProducts : { $cond: { if: { $isArray: "$Orderline" }, then: { $size: "$Orderline" }, else: "NA"} }}}])

MongoDB benchmarking inserts

I am trying to benchmark MongoDB with the JS harness. I am trying to do inserts. The example given in mongo website.
However, I am trying an insert operation, which works totally fine, but gives out wrong queries/sec.
ops = [{op: "insert", ns: "benchmark.bench", safe: false, doc: {"a": 1}}]
The above works fine. Then, I have run the following in mongo shell:
for ( x = 1; x<=128; x*=2){
res = benchRun( { parallel : x ,
seconds : 5 ,
ops : ops
} )
print( "threads: " + x + "\t queries/sec: " + res.query )
}
It gives out:
threads: 1 queries/sec: 0
threads: 2 queries/sec: 0
threads: 4 queries/sec: 0
threads: 8 queries/sec: 0
threads: 16 queries/sec: 0
threads: 32 queries/sec: 1.4
threads: 64 queries/sec: 0
threads: 128 queries/sec: 0
I dont understand why the queries/sec is 0 and not a single doc has been inserted. Is this right was testing performance for inserts?
Answering because I just encountered a similar problem.
Try replacing your print statement with printjson(res).
You will see that res has the following fields:
{
"note" : "values per second",
"errCount" : NumberLong(0),
"trapped" : "error: not implemented",
"insertLatencyAverageMicros" : 8.173300153139357,
"totalOps" : NumberLong(130600),
"totalOps/s" : 25366.173139864142,
"findOne" : 0,
"insert" : 25366.173139864142,
"delete" : 0,
"update" : 0,
"query" : 0,
"command" : 0
}
As you can see, the query count is 0, hence when you print res.query it gives 0. To get the number of insert operations per second you would want to print res.insert. I believe res.query corresponds to the "find" operation.

How can I see all characters in a unicode category?

I've read the documentation and can't find any examples.
http://golang.org/pkg/unicode/#IsPunct
Is there a place in the documentation that explicitly lists all characters in these categories? I'd like to see what characters are contained in category P or category M.
It's not in the documentation, but you can still read the source code. The categories you're talking about are defined in this file: http://golang.org/src/pkg/unicode/tables.go
For example, the P category is defined this way:
2029 var _P = &RangeTable{
2030 R16: []Range16{
2031 {0x0021, 0x0023, 1},
2032 {0x0025, 0x002a, 1},
2033 {0x002c, 0x002f, 1},
2034 {0x003a, 0x003b, 1},
2035 {0x003f, 0x0040, 1},
2036 {0x005b, 0x005d, 1},
2037 {0x005f, 0x007b, 28},
...
2141 {0xff5d, 0xff5f, 2},
2142 {0xff60, 0xff65, 1},
2143 },
2144 R32: []Range32{
2145 {0x10100, 0x10102, 1},
2146 {0x1039f, 0x103d0, 49},
2147 {0x10857, 0x1091f, 200},
...
2157 {0x12470, 0x12473, 1},
2158 },
2159 LatinOffset: 11,
2160 }
And here is a simple way to print all of them:
var p = unicode.Punct.R16
for _, r := range p {
for c := r.Lo; c <= r.Hi; c += r.Stride {
fmt.Print(string(c))
}
}
There are a number of web sites that present an interface to the Unicode character database. For example see the “Punctuation, ...” categories at http://www.fileformat.info/info/unicode/category/.

$pull operation in MongoDB not working for me

I have a document with the following key-array pair:
"home" : [
"Kevin Garnett",
"Paul Pierce",
"Rajon Rondo",
"Brandon Bass",
" 5 sec inbound",
"Kevin Seraphin"
]
I want to remove the element " 5 sec inbound" from the array and use the following command (in the MongoDB shell):
>coll.update({},{"$pull":{"home":" 5 sec inbound"}})
This is not working as verified by a query:
>coll.findOne({"home":/5 sec inbound/})
"home" : [
"Kevin Garnett",
"Paul Pierce",
"Rajon Rondo",
"Brandon Bass",
" 5 sec inbound",
"Kevin Seraphin"
]
Any help would be greatly appreciated!
That very same statement works for me:
> db.test.insert({"home" : [
... "Kevin Garnett",
... "Paul Pierce",
... "Rajon Rondo",
... "Brandon Bass",
... " 5 sec inbound",
... "Kevin Seraphin"
... ]})
> db.test.find({"home":/5 sec inbound/}).count()
1
> db.test.update({},{"$pull":{"home":" 5 sec inbound"}})
> db.test.find({"home":/5 sec inbound/}).count()
0

mongodb: issues using $lte and $gte

look at this bizarre result:
list(db.users.find({"produit_up.spec.prix":{"$gte":0, "$lte": 1000}}, {"_id":0,"produit_up":1}))
Out[5]:
[{u'produit_up': [{u'avatar': {u'avctype': u'image/jpeg',
u'orientation': u'portrait',
u'photo': ObjectId('506867863a5f3a0ea84dcd6c')},
u'spec': {u'abus': 0,
u'date': u'2012-09-30',
u'description': u"portable tr\xe8s solide, peu servi, avec batterie d'une autonomie de 3 heures.",
u'id': u'alucaard134901952647',
u'namep': u'nokia 3310',
u'nombre': 1,
u'prix': 1000,
u'tags': [u'portable', u'nokia', u'3310'],
u'vendu': False}},
{u'avatar': {u'avctype': u'image/jpeg',
u'orientation': u'portrait',
u'photo': ObjectId('50686d013a5f3a04a8923b3e')},
u'spec': {u'abus': 0,
u'date': u'2012-09-30',
u'description': u'\u0646\u0628\u064a\u0639 \u0623\u064a \u0641\u0648\u0646 \u062c\u062f\u064a\u062f \u0641\u064a \u0627\u0644\u0628\u0648\u0627\u0637 \u0645\u0639\u0627\u0647 \u0634\u0627\u0631\u062c\u0648\u0631 \u062f\u0648\u0631\u064a\u062c \u064a\u0646',
u'id': u'alucaard134902092967',
u'namep': u'iphone 3gs',
u'nombre': 1,
u'prix': 20000,
u'tags': [u'iphone', u'3gs', u'apple'],
u'vendu': False}},
{u'avatar': {u'avctype': u'image/jpeg',
u'orientation': u'paysage',
u'photo': ObjectId('50686d3e3a5f3a04a8923b40')},
u'spec': {u'abus': 0,
u'date': u'2012-09-30',
u'description': u'vends 206 toutes options 2006 hdi.',
u'id': u'alucaard134902099082',
u'namep': u'peugeot 206',
u'nombre': 1,
u'prix': 500000,
u'tags': [u'voiture', u'206', u'hdi'],
u'vendu': False}}]}]
list(db.users.find({"produit_up.spec.prix":{"$gte":0, "$lte": 100}}, {"_id":0,"produit_up":1}))
Out[6]: []
pymongo.version
Out[8]: '2.3+'
and it gives me the same result in Mongo Shell:
db.version()
2.2.0
here is the answer from Bernie Hackett
You have three values for "produit_up.spec.prix", 1000, 20000, 500000.
Why would you think that {"$gte":0, "$lte": 100} would match any of
those values? 100 is less than all of those values.
The reason that {"$gte":0, "$lte": 1000} returns all three documents
is that they are all subdocuments in an array. Since one of the
subdocuments in the array is matched the entire enclosing document
is a match for your query. Since you did a projection on only
"produit_up", just that array (including all array members) is
returned. Use $elemMatch in MongoDB 2.2 to only return the exact
matching array element.
MongoDB and PyMongo are working as designed here.
To get the behavior I think you're asking for see the $elemMatch operator:
http://docs.mongodb.org/manual/reference/projection/elemMatch/