accessing mongodb's object from mapper (MapReduce) - javascript

I have an extra question based on the one I asked before:
calculate frequency using mongodb aggregate framework
so my data in MongoDB looks like this now:
{
"data": {
"interaction": {
"created_at": "Wed, 09 Apr 2014 14:38:16 +0000"
}
},
"_id": {
"$oid": "53455b59edcd5e4e3fdd4ebb"
}
}
before I used to have it like:
[
{
created_at: "2014-03-31T22:30:48.000Z",
id: 450762158586880000,
_id: "5339ec9808eb125965f2eae1"
}
]
so to access created_at I was using mapper like:
var mapper = function () {
if ( this.created_at.getTime() > ( last_date + 10000 ) ) {
...
but as the structure in my database has changed, I tried to change:
this.created_at.getTime()
to:
this.data.interaction.created_at.getTime()
but unfortunately it didn't work out. Thank you for any help

Hate to make this that simple but all you want to do when importing these date strings is this:
new Date("Wed, 09 Apr 2014 14:38:16 +0000")
Which will return a proper date type that you actually should be inserting as part of your data.

Related

reading output of API in react

I am calling one API in react. for that I am getting output in below format.
{
"first_page_uri": "/2010-04-01/Accounts/xxxxxxxxxxxxxxxxx/Messages.json?PageSize=50&Page=0",
"end": 49,
"previous_page_uri": null,
"messages": [
{
"body": "",
"num_segments": "1",
"direction": "outbound-api",
"from": "+12058557185",
"date_updated": "Mon, 29 Aug 2022 09:07:47 +0000",
"price": "-0.04410",
"error_message": null,
"uri": "/2010-04-01/Accounts/xxxxxxxxxxxxxxxxx/Messages/xxxxxxxxxxxxxxxxx.json",
"account_sid": "xxxxxxxxxxxxxxxxx",
"num_media": "0",
"to": "+919823772514",
"date_created": "Mon, 29 Aug 2022 09:07:42 +0000",
"status": "delivered",
"sid": "SMfa2e62cf71761db915657b02605bc689",
"date_sent": "Mon, 29 Aug 2022 09:07:43 +0000",
"messaging_service_sid": "xxxxxxxxxxxxxxxxx",
"error_code": null,
"price_unit": "USD",
"api_version": "2010-04-01",
"subresource_uris": {
"media": "/2010-04-01/Accounts/xxxxxxxxxxxxxxxxx/Messages/xxxxxxxxxxxxxxxxx/Media.json",
"feedback": "/2010-04-01/Accounts/xxxxxxxxxxxxxxxxx/Messages/xxxxxxxxxxxxxxxxx/Feedback.json"
}
},
{
"body": "",
"num_segments": "1",
"direction": "outbound-api",
"from": "+12058557185",
"date_updated": "Mon, 29 Aug 2022 05:51:57 +0000",
"price": "-0.04410",
"error_message": null,
"uri": "/2010-04-01/Accounts/xxxxxxxxxxxxxxxxx/Messages/xxxxxxxxxxxxxxxxx.json",
"account_sid": "AC9ab9e25e89eaa96c474e9a39867bb2f3",
"num_media": "0",
"to": "+919823772514",
"date_created": "Mon, 29 Aug 2022 05:51:47 +0000",
"status": "delivered",
"sid": "SM5237fb62ff472b5e124fdd2ea073fffe",
"date_sent": "Mon, 29 Aug 2022 05:51:47 +0000",
"messaging_service_sid": "MG00d095919337aa95aeb5b74c8f0bd81c",
"error_code": null,
"price_unit": "USD",
"api_version": "2010-04-01",
"subresource_uris": {
"media": "/2010-04-01/Accounts/xxxxxxxxxxxxxxxxx/Messages/xxxxxxxxxxxxxxxxx/Media.json",
"feedback": "/2010-04-01/Accounts/xxxxxxxxxxxxxxxxx/Messages/xxxxxxxxxxxxxxxxx/Feedback.json"
}
},
{
"body": "",
"num_segments": "1",
"direction": "outbound-api",
"from": "+12058557185",
"date_updated": "Mon, 29 Aug 2022 05:24:09 +0000",
"price": "-0.04410",
"error_message": null,
"uri": "/2010-04-01/Accounts/xxxxxxxxxxxxxxxxx/Messages/xxxxxxxxxxxxxxxxx.json",
"account_sid": "xxxxxxxxxxxxxxxxx",
"num_media": "0",
"to": "+919727930925",
"date_created": "Mon, 29 Aug 2022 05:24:05 +0000",
"status": "delivered",
"sid": "SM1528c06455368cfb7e00ab8283ed773c",
"date_sent": "Mon, 29 Aug 2022 05:24:05 +0000",
"messaging_service_sid": "MG00d095919337aa95aeb5b74c8f0bd81c",
"error_code": null,
"price_unit": "USD",
"api_version": "2010-04-01",
"subresource_uris": {
"media": "/2010-04-01/Accounts/xxxxxxxxxxxxxxxxx/Messages/xxxxxxxxxxxxxxxxx/Media.json",
"feedback": "/2010-04-01/Accounts/xxxxxxxxxxxxxxxxx/Messages/xxxxxxxxxxxxxxxxx/Feedback.json"
}
}
,`
I want to read differnet fields on it to perform some operation in UI.
for example I want to read status, body, from etc.
alert("Message is:"+JSON.stringify(response.data))
this line is giving output of an API properly.
but when I write
alert("Message is:"+JSON.stringify(response.data.messages))
alert("Message is:"+JSON.stringify(response.data.messages.from))
alert("Message is:"+JSON.stringify(response.data.messages[0].from))
I am getting undefined and exceptions. my goal is to print the value in UI for specific status.
Can somrebody help me on that.
I tried lot of options and googling but nothing helped. I am new to javascript
Now this is a relatively complex topic for a beginner, let's start at the beginning.
Objects
What you get from the api request is an object. An object has properties, like first_page_uri, end, and so on. In JSON that will look like this:
{
"first_page_uri": "this is a value",
"end": 42
}
If you parsed the json string to a javascript object, like I assume you already have. You will have your object handle / variable. In your case that should be response.data.
With that handle you are able to get those object properties by accessing them using . after the handle and their name. For example you can display first_page_uri by writing this:
alert(response.data.first_page_uri)
Lists (Arrays)
Inside the response, there is a list. A list in JSON is represented like this:
"my_list": [
"a",
"b",
"c"
]
In this case the list has 3 values containing the strings a, b and c.
If you have a list in javascript, to get any of the values you can do the following:
alert(my_list[index])
Where my_list is the list and index is a value between 0 for the first element a and in this case 2 for the last element c.
Caution: we start counting from 0.
To show b in an alert we would write:
alert(my_list[1])
Combination of both
The attribute messages in your response is such a list. It contains not strings, but objects. Like so:
{
"messages": [
{
"body": "this is a message"
},
{
"body": "this is another message"
}
]
}
In this case if you wanted to retrieve the first message body and alert it, you would need to combine both patterns from above:
alert(response.body.messages[0].body)
I am assuming your object is in response.body. We are accessing messages and then selecting the first with [0] and then selecting body from that message.
Possible solutions
The problems you are encountering are probably the following:
alert is only able to show simple data types like string, number and so on. So trying to print out a whole list for example will not work.
I assume your other code is correct by the fact that you say that:
alert("Message is:"+JSON.stringify(response.data))
works.
All you would need to do to fix your code, is to remove the second line:
alert("Message is:"+JSON.parse(response.data.messages.from))
.from makes js try to access a property of a list. As discussed above. Objects have properties, lists do not. So react throws an exception.
Your other lines:
alert("Message is:"+JSON.stringify(response.data.messages))
alert("Message is:"+JSON.stringify(response.data.messages[0].from))
should work. As they seem to be correct.
The UI
Now regarding the UI part you are talking about...
If you are inside a react component, which would probably look somewhat like this:
const ComponentName = (/* maybe stuff here */) => {
// maybe a lot of stuff here
return (
/* this is the interesting part */
)
}
You want to be looking for the return part.
Inside there you can write HTML-like code. A simple UI output to show all messages would be:
const ComponentName = () => {
// here you do your api stuff so you get the response variable
const response;
return (
<>
<h1>All messages:</h1>
{
response.body.messages.map((message) => (
<p>{message.body}</p>
))
}
</>
)
}
I did use a new thing here: the map function on a list. I put it in the recommended reading section below.
The part in the middle:
<h1>All messages:</h1>
{
response.body.messages.map((message) => (
<p>{message.body}</p>
))
}
Is the important part. You can more or less put it anywhere in the return statement and it should show up.
Recommended reading
To learn more you probably want to look up the following things:
Arrays
Array (map function)
Object (literals)
React (quick start tutorial)
My thoughts (please ignore if unsuited)
If you are very new to javascript and this is a free time project. I would recommend taking it a step slower. While I do not want to discourage you from continuing with what you are doing, I assume that you can learn quicker and more effectively by stepping back and for example start with a HTML, CSS and JS only project without libraries. That should make you more comfortable in the concepts involved before jumping into a more complicated project. Especially if you do not have much or any experience with other languages.
A good start for that would be this project. It does include jQuery, but you do not need to use it.
I wish you the best of luck going forward!
You should use JSON.parse instead of JSON.stringify.
JSON.parse convert json string to js object and JSON.stringify do the reversed job.
So, your code should look like:
alert("Message is:"+JSON.parse(response.data.messages))
alert("Message is:"+JSON.parse(response.data.messages.from))
alert("Message is:"+JSON.parse(response.data.messages[0].from))
One more note here, to access nested property in JS object and avoid access anything from undefined, you should use JS optional chaining feature like below:
alert("Message is:"+JSON.parse(response?.data?.messages))
alert("Message is:"+JSON.parse(response?.data?.messages?.from))
The ? take care of null check for you.
Try this, but first replace this api with your api
import React from 'react';
import './style.css';
class App extends React.Component {
constructor() {
super();
this.state = {
data: null,
};
}
componentDidMount() {
fetch('https://reqres.in/api/users') // replace this api with your api
.then((response) => {
response.json().then((result) => {
console.warn(result.data);
this.setState({ data: result.data });
});
});
}
render() {
return (
<div>
{this.state.data
? this.state.data.map((item, i) => (
<div>
<p>
{i} --- {item.body} {item.from}{' '}
</p>
</div>
))
: null}
</div>
);
}
}
export default App;

Snapshot shows timezone name instead of GMT code in CI server

I'm using a snapshot test in my project and came across a weird problem when running this specific test on a CI server: it displays the timezone name instead of the GMT code, causing the test failure.
I have tried using "moment-timezone" and Date.UTC() to normalize the dates, the result shown was the correct date with the same issue as above.
I've also tried to stub the global.Date object, but the components complained about prop incompatibility.
it('should render with props', () => {
const order = {
merchant: { logo: 'abc', name: 'Pizza Hut' },
bag: {
items: [{ name: 'Corn & Bacon' }],
total: {
valueWithDiscount: 99.99,
},
},
delivery: {
deliversAt: new Date('2019-05-21 13:00'),
},
payment: {
mode: 'online',
},
lastStatus: API_STATUSES.cancelled,
createdAt: new Date('2019-05-21 12:00'),
details: {},
};
const wrapper = shallowMount(Order, {
...commons,
propsData: { order },
});
expect(wrapper).toMatchSnapshot();
});
See that the expected date is the same as the received one, but syntactic differences:
<div class="order__details">
- <orderdetails-stub paymentmode="online" deliverytime="Fri Jun 21 2019 10:00:00 GMT-0300 (GMT-03:00)" value="99.99" laststatus="cancelled"></orderdetails-stub>
+ <orderdetails-stub paymentmode="online" deliverytime="Fri Jun 21 2019 10:00:00 GMT-0300 (Brasilia Standard Time)" value="99.99" laststatus="cancelled"></orderdetails-stub>
Using Date strings as props like this is hazardous and likely to lead to the sort of problem you're encountering.
Best practice for tests in my experience is to use Date.getTime() so values are numbers of milliseconds without any locale information.
Alternatively, you can use moment-timezone as described in this article:
import moment from 'moment-timezone';
it('renders without crashing', () => {
moment.tz.setDefault('EST');
let props = {
currentDay: moment("2017-09-15 09:30:00").format("MMM Do YYYY h:mm:ss a")
};
const tree = renderer.create(<App {...props} />).toJSON();
expect(tree).toMatchSnapshot();
});

How to query for date ignoring its time in ISODate value [duplicate]

I've been playing around storing tweets inside mongodb, each object looks like this:
{
"_id" : ObjectId("4c02c58de500fe1be1000005"),
"contributors" : null,
"text" : "Hello world",
"user" : {
"following" : null,
"followers_count" : 5,
"utc_offset" : null,
"location" : "",
"profile_text_color" : "000000",
"friends_count" : 11,
"profile_link_color" : "0000ff",
"verified" : false,
"protected" : false,
"url" : null,
"contributors_enabled" : false,
"created_at" : "Sun May 30 18:47:06 +0000 2010",
"geo_enabled" : false,
"profile_sidebar_border_color" : "87bc44",
"statuses_count" : 13,
"favourites_count" : 0,
"description" : "",
"notifications" : null,
"profile_background_tile" : false,
"lang" : "en",
"id" : 149978111,
"time_zone" : null,
"profile_sidebar_fill_color" : "e0ff92"
},
"geo" : null,
"coordinates" : null,
"in_reply_to_user_id" : 149183152,
"place" : null,
"created_at" : "Sun May 30 20:07:35 +0000 2010",
"source" : "web",
"in_reply_to_status_id" : {
"floatApprox" : 15061797850
},
"truncated" : false,
"favorited" : false,
"id" : {
"floatApprox" : 15061838001
}
How would I write a query which checks the created_at and finds all objects between 18:47 and 19:00? Do I need to update my documents so the dates are stored in a specific format?
Querying for a Date Range (Specific Month or Day) in the MongoDB Cookbook has a very good explanation on the matter, but below is something I tried out myself and it seems to work.
items.save({
name: "example",
created_at: ISODate("2010-04-30T00:00:00.000Z")
})
items.find({
created_at: {
$gte: ISODate("2010-04-29T00:00:00.000Z"),
$lt: ISODate("2010-05-01T00:00:00.000Z")
}
})
=> { "_id" : ObjectId("4c0791e2b9ec877893f3363b"), "name" : "example", "created_at" : "Sun May 30 2010 00:00:00 GMT+0300 (EEST)" }
Based on my experiments you will need to serialize your dates into a format that MongoDB supports, because the following gave undesired search results.
items.save({
name: "example",
created_at: "Sun May 30 18.49:00 +0000 2010"
})
items.find({
created_at: {
$gte:"Mon May 30 18:47:00 +0000 2015",
$lt: "Sun May 30 20:40:36 +0000 2010"
}
})
=> { "_id" : ObjectId("4c079123b9ec877893f33638"), "name" : "example", "created_at" : "Sun May 30 18.49:00 +0000 2010" }
In the second example no results were expected, but there was still one gotten. This is because a basic string comparison is done.
To clarify. What is important to know is that:
Yes, you have to pass a Javascript Date object.
Yes, it has to be ISODate friendly
Yes, from my experience getting this to work, you need to manipulate the date to ISO
Yes, working with dates is generally always a tedious process, and mongo is no exception
Here is a working snippet of code, where we do a little bit of date manipulation to ensure Mongo (here i am using mongoose module and want results for rows whose date attribute is less than (before) the date given as myDate param) can handle it correctly:
var inputDate = new Date(myDate.toISOString());
MyModel.find({
'date': { $lte: inputDate }
})
Python and pymongo
Finding objects between two dates in Python with pymongo in collection posts (based on the tutorial):
from_date = datetime.datetime(2010, 12, 31, 12, 30, 30, 125000)
to_date = datetime.datetime(2011, 12, 31, 12, 30, 30, 125000)
for post in posts.find({"date": {"$gte": from_date, "$lt": to_date}}):
print(post)
Where {"$gte": from_date, "$lt": to_date} specifies the range in terms of datetime.datetime types.
db.collection.find({"createdDate":{$gte:new ISODate("2017-04-14T23:59:59Z"),$lte:new ISODate("2017-04-15T23:59:59Z")}}).count();
Replace collection with name of collection you want to execute query
MongoDB actually stores the millis of a date as an int(64), as prescribed by http://bsonspec.org/#/specification
However, it can get pretty confusing when you retrieve dates as the client driver will instantiate a date object with its own local timezone. The JavaScript driver in the mongo console will certainly do this.
So, if you care about your timezones, then make sure you know what it's supposed to be when you get it back. This shouldn't matter so much for the queries, as it will still equate to the same int(64), regardless of what timezone your date object is in (I hope). But I'd definitely make queries with actual date objects (not strings) and let the driver do its thing.
Use this code to find the record between two dates using $gte and $lt:
db.CollectionName.find({"whenCreated": {
'$gte': ISODate("2018-03-06T13:10:40.294Z"),
'$lt': ISODate("2018-05-06T13:10:40.294Z")
}});
Using with Moment.js and Comparison Query Operators
var today = moment().startOf('day');
// "2018-12-05T00:00:00.00
var tomorrow = moment(today).endOf('day');
// ("2018-12-05T23:59:59.999
Example.find(
{
// find in today
created: { '$gte': today, '$lte': tomorrow }
// Or greater than 5 days
// created: { $lt: moment().add(-5, 'days') },
}), function (err, docs) { ... });
db.collection.find({$and:
[
{date_time:{$gt:ISODate("2020-06-01T00:00:00.000Z")}},
{date_time:{$lt:ISODate("2020-06-30T00:00:00.000Z")}}
]
})
##In case you are making the query directly from your application ##
db.collection.find({$and:
[
{date_time:{$gt:"2020-06-01T00:00:00.000Z"}},
{date_time:{$lt:"2020-06-30T00:00:00.000Z"}}
]
})
You can also check this out. If you are using this method, then use the parse function to get values from Mongo Database:
db.getCollection('user').find({
createdOn: {
$gt: ISODate("2020-01-01T00:00:00.000Z"),
$lt: ISODate("2020-03-01T00:00:00.000Z")
}
})
Save created_at date in ISO Date Format then use $gte and $lte.
db.connection.find({
created_at: {
$gte: ISODate("2010-05-30T18:47:00.000Z"),
$lte: ISODate("2010-05-30T19:00:00.000Z")
}
})
use $gte and $lte to find between date data's in mongodb
var tomorrowDate = moment(new Date()).add(1, 'days').format("YYYY-MM-DD");
db.collection.find({"plannedDeliveryDate":{ $gte: new Date(tomorrowDate +"T00:00:00.000Z"),$lte: new Date(tomorrowDate + "T23:59:59.999Z")}})
mongoose.model('ModelName').aggregate([
{
$match: {
userId: mongoose.Types.ObjectId(userId)
}
},
{
$project: {
dataList: {
$filter: {
input: "$dataList",
as: "item",
cond: {
$and: [
{
$gte: [ "$$item.dateTime", new Date(`2017-01-01T00:00:00.000Z`) ]
},
{
$lte: [ "$$item.dateTime", new Date(`2019-12-01T00:00:00.000Z`) ]
},
]
}
}
}
}
}
])
For those using Make (formerly Integromat) and MongoDB:
I was struggling to find the right way to query all records between two dates. In the end, all I had to do was to remove ISODate as suggested in some of the solutions here.
So the full code would be:
"created": {
"$gte": "2016-01-01T00:00:00.000Z",
"$lt": "2017-01-01T00:00:00.000Z"
}
This article helped me achieve my goal.
UPDATE
Another way to achieve the above code in Make (formerly Integromat) would be to use the parseDate function. So the code below will return the same result as the one above :
"created": {
"$gte": "{{parseDate("2016-01-01"; "YYYY-MM-DD")}}",
"$lt": "{{parseDate("2017-01-01"; "YYYY-MM-DD")}}"
}
⚠️ Be sure to wrap {{parseDate("2017-01-01"; "YYYY-MM-DD")}} between quotation marks.
Convert your dates to GMT timezone as you're stuffing them into Mongo. That way there's never a timezone issue. Then just do the math on the twitter/timezone field when you pull the data back out for presentation.
Why not convert the string to an integer of the form YYYYMMDDHHMMSS? Each increment of time would then create a larger integer, and you can filter on the integers instead of worrying about converting to ISO time.
Scala:
With joda DateTime and BSON syntax (reactivemongo):
val queryDateRangeForOneField = (start: DateTime, end: DateTime) =>
BSONDocument(
"created_at" -> BSONDocument(
"$gte" -> BSONDateTime(start.millisOfDay().withMinimumValue().getMillis),
"$lte" -> BSONDateTime(end.millisOfDay().withMaximumValue().getMillis)),
)
where millisOfDay().withMinimumValue() for "2021-09-08T06:42:51.697Z" will be "2021-09-08T00:00:00.000Z"
and
where millisOfDay(). withMaximumValue() for "2021-09-08T06:42:51.697Z" will be "2021-09-08T23:59:99.999Z"
i tried in this model as per my requirements i need to store a date when ever a object is created later i want to retrieve all the records (documents ) between two dates
in my html file
i was using the following format mm/dd/yyyy
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<script>
//jquery
$(document).ready(function(){
$("#select_date").click(function() {
$.ajax({
type: "post",
url: "xxx",
datatype: "html",
data: $("#period").serialize(),
success: function(data){
alert(data);
} ,//success
}); //event triggered
});//ajax
});//jquery
</script>
<title></title>
</head>
<body>
<form id="period" name='period'>
from <input id="selecteddate" name="selecteddate1" type="text"> to
<input id="select_date" type="button" value="selected">
</form>
</body>
</html>
in my py (python) file i converted it into "iso fomate"
in following way
date_str1 = request.POST["SelectedDate1"]
SelectedDate1 = datetime.datetime.strptime(date_str1, '%m/%d/%Y').isoformat()
and saved in my dbmongo collection with "SelectedDate" as field in my collection
to retrieve data or documents between to 2 dates i used following query
db.collection.find( "SelectedDate": {'$gte': SelectedDate1,'$lt': SelectedDate2}})

Aggregate query in MongoDB using javascript trying to convert UTC string date to Date object

I'm trying to group datetimes by the hour and I am uploading data from a json file. The datetimes are in UTC format as strings though. How do I convert them to Date objects using javascript in meteor?
var data = Subjects.aggregate([{$match: no_null},
{ $project:
{ bin: { $hour: new Date("$metrics."+metric") }
} },
{$group: { _id: "$bin", count: {$sum: 1} } } ])
Metric is already in UTC format.
Here is one document.
{
"metrics": {
"ACT_04": 3.733333333,
"ACT_05": 14.5,
"ACT_02": "1970-01-01T05:02:30Z",
"ACT_03": 7.0833333329999997,
"ACT_01": "1970-01-01T20:03:00Z"
},
"subject_id": "M10965219",
"name": "sub-M10965219_Act"
}
If the "string" is in "lexical" ISO Format as in "2018-05-15T20:59:31.502Z", then you "could" get the $substr parts:
Subjects.aggregate([
{ "$group": {
"_id": { "$substr": ["$metrics."+metric,0,10] },
"count": { "$sum": 1 }
}}
])
If you have MongoDB 3.6 available then you "could" use $dateFromString to actually get that into a BSON date format, but you probably want to similarly truncate that string in a similar way for any date rounding you actually want:
Subjects.aggregate([
{ "$group": {
"_id": {
"$dateFromString": {
"dateString": { "$substr": ["$metrics."+metric,0,10] }
}
},
"count": { "$sum": 1 }
}}
])
MongoDB 4.0 has $toDate for a little shorter and does the same BSON Date conversion:
Subjects.aggregate([
{ "$group": {
"_id": {
"$toDate": { "$substr": ["$metrics."+metric,0,10] }
},
"count": { "$sum": 1 }
}}
])
But the basic fact this if your "string" does not actually look like that and cannot really be broken into parts of the string in a consistent way by supported operators, then you are generally far better off converting the dates stored in your collection(s) to be actual BSON Dates in the first place.
The "recommended" thing to do here is instead to actually run the conversion of the data. The mongo shell should be sufficient to run "one-off" conversions:
var batch = [];
db.subjects.find().forEach(doc => {
var fields = Object.keys(doc.metrics).map(k => ({
['metrics.'+k]: new Date(doc.metrics[k]),
})).reduce((acc,curr) => Object.assign(acc,curr),{});
batch.push({
"updateOne": {
"filter": doc._id",
"update": { "$set": fields }
}
});
if ( batch.length > 1000 ) {
db.subjects.bulkWrite(batch);
batch = []
}
})
if ( batch.length > 0 ) {
db.subjects.bulkWrite(batch);
batch = [];
}
That's the basic process. Of course if your "strings" are not in an ISO Format or any suitable for passing to Date() for conversion, then you'll actually need to take other measures.
At the very least a BSON Date is is an 8-btye data structure with an "internal" numeric representation, where as the equivalent "string" it at least 24-bytes and even longer with words naming days and months. It makes sense to keep data that is essentially "numeric" in nature in that form when working with a database.
My advice is to convert the data, and possibly on import or if you cannot work that out then at least once loaded to the collection. It's better that trying to work with strings for something they are really not meant to do.
Note $substr is considered deprecated and actually now aliases $substrBytes, or you can use $substrCP depending on the actual encoding of the data. Older MongoDB releases before 3.2 have the $substr expression only.

Modifying mongoose object literal result does not work [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why can’t you modify the data returned by a Mongoose Query (ex: findById)
First I am making the query to mongoDB, get all the correct results but only the small modification to object literal does not work. What I am trying to do, is adding new field to comments. I tried to use the DBref method but it didn't work so i make 2 queries now.
var query = Rss.findOne({ _id: itemId});
query.exec(function(err, feed) {
if (!err && feed.comments) {
console.log(feed.comments.length);
for (var index in feed.comments) {
var author = feed.comments[index].author;
if (author !== undefined) {
User.findById(author, function(err, user) {
/**Problem is here **/
feed.comments[index].name = 'Some random field';
console.log('Added new field' + util.inspect(feed));
});
}
}
}
});
Also the response is this without the missing .name field.
Added new field{ _id: 4f34f343c7b0434217000012,
original_link: 'http://com',
publish_date: Fri, 10 Feb 2012 10:36:00 GMT,
summary: 'some text',
title: 'title exampel',
comments:
[ { body: 'well',
author: 4f30265e6f60dc061d000002,
_id: 4f34f3b6f96c58541700000f,
create_date: Fri, 10 Feb 2012 10:38:46 GMT } ],
create_date: Fri, 10 Feb 2012 10:36:51 GMT }
// EDIT more information
Well i haven't found the answer but some how the console.log(feed.comments[index]) returns reference to function. Maybe someone who has more experience with mongoosejs could explain what would be workaround in this situation.
{ [Function] author: 'Some random field' }
You have to tell Mongoose to convert the result into a proper object. Before modifying the feed object simply call:
feed = feed.toObject();
And then you can add all the additional properties you want to it.

Categories