Querying a list in MongoDB - mongodb

I have a document that looks like this:
{
"_id" : ObjectId("570fc2381d4899be8a8ec9d9"),
"statuses" : [
{
"created_at" : "Wed Apr 13 09:56:39 +0000 2016",
"id" : 7.20188946337153e+017,
"id_str" : "720188946337153024",
"text" : "RT #BCC_Assicura: #FormulaAuto la #polizza #Auto e #Moto economica BccPordenonese - #BCC #Assicurazioni #Click2go"
},
{
"created_at" : "Wed Apr 13 09:40:13 +0000 2016",
"id" : 7.20184809658708e+017,
"id_str" : "720184809658707970",
"text" : "Auto e moto storiche, vademecum su assicurazione e bollo - \n#autostoriche #bollo #RCauto #ASI #FMI"
}
]}
How do I query for all the records where the variable text contains the string "assicur"?
Thank you!

One possibility would be to use a regex;
> db.test.find({"statuses.text":{$regex: 'assicur'}})
That said, this will not be possible to index in mongodb, so it's probably best done along with other filters that cut the documents down to a small set before doing the string matching.

Related

How to avoid duplicate values ? [duplicate]

This question already has answers here:
Return document in each group with max value using MongoDB
(2 answers)
Closed 4 years ago.
I am new to Mongo Db and would appreciate some help with this query.my mongodb data transection same ids number of thre based on create_date how to display each transection id first record
db.collection.aggregate([{
{"$project": {
"RESOURCE_ID": 1,
"TRANSACTION_ID":1,
"CREATE_DATE":1
}}
])
output:
RESOURCE_ID TRANSACTION_ID CREATE_DATE
1 "100-101" "0:ffff0a0a0983UY:-142" "Fri Sep 07 16:51:30IST2018"
2 "100-101" "0:ffff0a0a0983UY:-142" "Fri Sep 07 16:51:29IST2018"
3 "100-101" "0:ffff0a0a0983UY:-142" "Fri Sep 07 16:51:29IST2018"
4 "100-102" "0:ffff0a0a0983UY:-111" "Fri Sep 06 16:51:29IST2018"
5 "100-102" "0:ffff0a0a0983UY:-111" "Fri Sep 06 16:51:28IST2018"
expected output:
RESOURCE_ID TRANSACTION_ID CREATE_DATE
1 "100-101" "0:ffff0a0a0983UY:-142" "Fri Sep 07 16:51:30IST2018"
2 "100-102" "0:ffff0a0a0983UY:-111" "Fri Sep 06 16:51:29IST2018"
This is what you want:
db.collection.aggregate([{"$sort": {CREATE_DATE: 1}},{$group:{"_id": "$RESOURCE_ID", TRANSACTION_ID: {$first: "$TRANSACTION_ID"}, "CREATE_DATE": {$first: "$CREATE_DATE"}}}])
What it does - sorts all the documents by the date, in an ascending order, because we want the oldest document first (notice the sort clause).
Then, it groups the documents by the field "RESOURCE_ID" (which is marked as the new _id), and takes the $first TRANSACTION_ID and $first CREATE_DATE.
Notice that you will have to convert your timestamps to actual timestamps, in order for mongo to really understand the order of the timestamps. Otherwise mongo will sort them as strings, and this isn't what you want
An example:
> db.collection.find().pretty()
{
"_id" : ObjectId("5bd2bf353ca22147747ec212"),
"RESOURCE_ID" : "100-101",
"TRANSACTION_ID" : "0:ffff0a0a0983UY:-142",
"CREATE_DATE" : ISODate("2017-10-13T10:53:53Z")
}
{
"_id" : ObjectId("5bd2bf3c3ca22147747ec213"),
"RESOURCE_ID" : "100-101",
"TRANSACTION_ID" : "0:ffff0a0a0983UY:-142",
"CREATE_DATE" : ISODate("2017-10-14T10:53:53Z")
}
{
"_id" : ObjectId("5bd2bf3c3ca22147747ec214"),
"RESOURCE_ID" : "100-102",
"TRANSACTION_ID" : "0:ffff0a0a0983UY:-111",
"CREATE_DATE" : ISODate("2017-10-13T10:53:53Z")
}
{
"_id" : ObjectId("5bd2bf3c3ca22147747ec215"),
"RESOURCE_ID" : "100-102",
"TRANSACTION_ID" : "0:ffff0a0a0983UY:-111",
"CREATE_DATE" : ISODate("2017-10-14T10:53:53Z")
}
> db.collection.aggregate([{"$sort": {CREATE_DATE: 1}},{$group:{"_id": "$RESOURCE_ID", TRANSACTION_ID: {$first: "$TRANSACTION_ID"}, "CREATE_DATE": {$first: "$CREATE_DATE"}}}])
{ "_id" : "100-102", "TRANSACTION_ID" : "0:ffff0a0a0983UY:-111", "CREATE_DATE" : ISODate("2017-10-13T10:53:53Z")
{ "_id" : "100-101", "TRANSACTION_ID" : "0:ffff0a0a0983UY:-142", "CREATE_DATE" : ISODate("2017-10-13T10:53:53Z")
Also, worth mentioning that you should add indexes for CREATE_DATE because you are sorting by this field, and to RESOURCE_ID because mongo has to sort it in order to group by it

Date query in mongodb isn't working

Type of document
{
"_id" : ObjectId("585232c2bbdfc4243ecf2670"),
"field1" : "value1",
"date" : "Mon Dec 19 2016 14:45:17 GMT+0530 (IST)",
"field2" : "value2",
"field3" : true
}
Query used:
db.myCollection.find({"date":{"$lt":new Date()}})
I want to run this query on 12:05 AM to fetch all past records upto
yesterday 23:59:59
It seems that the value is a string and not a Date.
fields of type Date should appear like this:
"date" : ISODate("2016-12-19T14:45:17.000Z");
and not like what you're seeing.
Make sure you save a Date object into the collection, and not a string representation of it.

Deal with accented character in mongodb

I've been struggling to find an ideal way to deal with accented characters.
First i use this two methods to encode(decode) text before inserting(fetching) in mongo.
function encode_utf8(s) {
return unescape(encodeURIComponent(s));
}
function decode_utf8(s) {
return decodeURIComponent(unescape(s));
}
This method works fine when i fetch comments from mongodb and display them (ajax request) :
$.ajax({
url : "http:www.mywebsite.com/comments",
type : "get",
data : "key=" + env.key + "&login=" + login,
dataType : "json",
success: function(response) { console.log(decode_utf8(reponse.texte)); /* yay works fine */ },
error : function(jqXHR, textStatus, errorThrown) {}
});
But when i use the code (map function of MapReduce) below it's doesn't handle accent:
String map = "function map() { "
+ "var texte = decodeURIComponent(unescape(this.comment));"
+ "var words = texte.match(/\\w+/g);"
+ "if(words) "
+ for(var i=0; i<words.length; i++)
+ emit(words[i].toLowerCase(), 1);"
+ "}"
Ex: Instead of ùùdzedzed the result is dzedzed.
Any suggestion or workaround would be great.
EDIT :
My mongo content :
{ "_id" : ObjectId("55460441e4b00700737c56cc"), "id" : "c0ab4be5-f4f3-4c73-a7a0-f6863b6ce6511430651969105", "auteur_login" : "testlogin", "auteur_id" : 1, "comment" : "être où règlem ça", "date" : "Sun May 03 13:19:29 CEST 2015" }
{ "_id" : ObjectId("554612f1e4b0953aca0c0be0"), "id" : "aaa52859-5de6-469b-a17f-aa4615db77f71430655729171", "auteur_login" : "testlogin", "auteur_id" : 1, "comment" : "à la", "date" : "Sun May 03 14:22:09 CEST 2015" }
{ "_id" : ObjectId("55461c21e4b0643ea96f7933"), "id" : "ba3ae7c0-39a6-4c77-86ec-d193e39759b71430658081921", "auteur_login" : "testlogin", "auteur_id" : 1, "comment" : "voilà", "date" : "Sun May 03 15:01:21 CEST 2015" }
{ "_id" : ObjectId("5547f5ede4b055c2ffb1a592"), "id" : "a9a1e7d4-c28d-4f9e-98d5-3fe7fba3bb5e1430779373121", "auteur_login" : "testlogin", "auteur_id" : 1, "comment" : "vb vb vb", "date" : "Tue May 05 00:42:53 CEST 2015" }
{ "_id" : ObjectId("5547f5fbe4b055c2ffb1a593"), "id" : "b5ad2b7e-987f-4d32-b5ca-bc06bdc57f611430779387478", "auteur_login" : "testlogin", "auteur_id" : 1, "comment" : "vb vb", "date" : "Tue May 05 00:43:07 CEST 2015" }
{ "_id" : ObjectId("5548b88ee4b029bc67d7a638"), "id" : "451e4e0d-c15a-4657-82c3-7760555b6c811430829198040", "auteur_login" : "testlogin", "auteur_id" : 1, "comment" : "ecrit n'importe quoi", "date" : "Tue May 05 14:33:18 CEST 2015" }
{ "_id" : ObjectId("554b9409e4b004c1b252f9cb"), "id" : "f36c3b49-72b1-48f4-ae92-a7933bc1e2761431016457515", "auteur_login" : "moi12345", "auteur_id" : 9, "comment" : "salut", "date" : "Thu May 07 18:34:17 CEST 2015" }
{ "_id" : ObjectId("554b941be4b004c1b252f9cd"), "id" : "1adc6788-32be-4c3a-bd73-16dad0b4bb741431016475777", "auteur_login" : "moi12345", "auteur_id" : 9, "comment" : "regregerhg", "date" : "Thu May 07 18:34:35 CEST 2015" }
And this is the result :
"sfsdfs": 58.0 update
"ta": 58.0 update
"test1": 58.0 update
"teste": 9.666666666666666 update
"ton": 58.0 update
"tre": 29.0 insert
"try": 58.0 update
"tudiant": 58.0 insert
"tweed": 58.0 update
"une": 58.0 update
"va": 19.333333333333332 update
"vb": 29.0 update
"veux": 19.333333333333332 update
"vient": 58.0 update
"voil": 58.0 insert
Example: the last line i should be getting voilàinstead of voil
So, essentially, your "encode_utf8" method does a weird way of converting UTF-8 string into 8-bit bytes. Why are you doing that?
([de/en]codeURIComponent() uses UTF-8 encoding, [un]encode uses ISO-8859-1)
For symmetry, your "decode_utf8(s)" shall be
return decodeURIComponent(escape(s));
instead of "unescape".
Note that escape() and unescape() Javascript methods are deprecated
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/escape
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/unescape

How do I use Field Selection to return a contained field with the Mongo shell?

I am storing Tweets in a MongoDB database, and would like to use Field Selectors (http://www.mongodb.org/display/DOCS/Querying#Querying-FieldSelection) to return just the text, the date and the screen name of the user.
{
"_id" : NumberLong("213686009408"),
"text" : "RT #Milanello: Lightning over the Donb...",
"created_at" : "Fri, 15 Jun 2012 17:37:38 +0000",
"user" : {
"screen_name" : "xxxxx",
"profile_image_url" : "http://a0.twimg.com/pro[...].jpg"
}
}
Creating a query that returns just the text and date is easy enough:
> db.abc.find({},{created_at:1,text:1})
I'm not sure how to return the user.screen_name property as well?
[UPDATE]
I had previously tried using the dot notation and it threw an exception, however, as per both answers below (I have +1'd both) the dot notation does work, but only if you use "" around the attribute names.
So, this does NOT work:
db.abc.find({},{created_at:1,text:1, user.screen_name:1})
But this DOES:
db.abc.find({},{created_at:1,text:1, "user.screen_name":1})
You can use dot notation as you would in a query:
db.abc.find({},{created_at:1,text:1, "user.screen_name" : 1})
However, the field will not be flattened, so the result objects still have a user-subdocument:
{ "_id" : NumberLong("4546545"),
"created_at" : "Fri, 15 Jun...",
"user" : { "screen_name" : "John Doe" }
}
However, flattening this in code shouldn't be a big problem.
You need to use dot notation to query for values within the array. I created a similar document, modified the _id field, and ran the following queries successfully -
> db.abc.find({},{'user.screen_name': 1})
{ "_id" : 1200, "user" : { "screen_name" : "xxxxx" } }
> db.abc.find({'user.screen_name': "xxxxx"})
{ "_id" : 1200, "text" : "RT #Milanello: Lightning over the Donb...", "created_at" : "Fri, 15 Jun 2012 17:37:38 +0000", "user" : { "screen_name" : "xxxxx", "profile_image_url" : "http://a0.twimg.com/pro[...].jpg" } }
There's more infomation on advanced queries here.
Update: Looks like I posted this 2 minutes after mnemosyn so accept his answer first.

Emit a DateTime in the Map function of MongoDb

My map function looks like this:
map = function()
{
day = Date.UTC(this.TimeStamp.getFullYear(), this.TimeStamp.getMonth(), this.TimeStamp.getDate());
emit({day : day, store_id : this.Store_Id}, {count : 1});
}
TimeStamp is stored as date in the database, like this:
{ "TimeStamp" : "Mon Mar 01 2010 11:58:09 GMT+0000 (BST)", ...}
I need the "day" in the result collection to be stored as a date type as well, but it's stored as long (Epoch ticks) like this:
{ "_id" : { "day" : 1265414400000, "store_id" : 10}, "value" : { "count" : 7 } }
I tried changing the emit to something like this but didn't help:
emit({day : {"$date" : day},...)
Any ideas as to how to do that?
Date.utc is going to return miliseconds from epoch. So when you put your data back into the DB, you can use for example:
new Date(dateAsLong)
and it will be stored as the BSON date format.
earlier than mongo 1.7 it will show up in your hash as:
"Mon Mar 01 2010 11:58:09 GMT+0000 (BST)"
1.7+ it will appear as:
ISODate("2010-03-01T11:58:09Z")