Save ServerValue.TIMESTAMP as string in realtime database - java

I'm trying to save the firebase timestamp as a string, I'm using realtime database, I want to arrange my nodes based on their post date and I want to exclude those posts that are older than 24 h.
my node structure is something like this
"posts" : {
"b" : {
"text" : "5",
"timestamp" : "{.sv=timestamp}",
"uid" : "KpZvp0bhOlPJI3KKwe1AF7Apb2U2"
},
"a" : {
"text" : "hey",
"timestamp" : "1559912589250",
"uid" : "KpZvp0bhOlPJI3KKwe1AF7Apb2U2"
}
}
I have no problem arranging the posts based on the date but when I want to exclude the posts that are older than 24 h that's when I start having trouble
firebaseDatabase.reference.child("posts").orderByChild("timestamp").startAt((System.currentTimeMillis() - 86400000))
the "startAt()" doesn't take long or integers it only takes boolean, strings and double as parameters.
this is how I create the nodes
firebaseDatabase.reference.child("posts").push().setValue(mapOf(
"by" to uid,
"text" to "hey",
"timestamp" to ServerValue.TIMESTAMP)
)
I tried changing the ServerValue.TIMESTAMP to string but it saves it as "{".sv" : "timestamp"}" I looked around and I found out that if I send a map with an index that is named ".sv" and has the value of "timestamp" so that the database will recognize it and replace the value with the server timestamp
something like this
firebaseDatabase.reference.child("posts").push().setValue(mapOf(
"by" to uid,
"text" to "hello",
"timestamp" to mapOf(".sv" to "timestamp")
the timestamp value will be the server timestamp as a long number, so basically the ServerValue.TIMESTAMP is like a map, that's why when I tried changing it to a string it gave me "{".sv" : "timestamp"}" value.
So how can I save the server timestamp as a string? or how can I query the data as a Long number without changing it to string

Related

Cassandra Saving JSON data in Text Column

In Cassandra DB I have column name as custom_extensions which can contain List<AppEncoded> where AppEncoded is an UDT. The UDT has following fields
type -> TEXT
code -> TEXT
value - TEXT
While saving data to DB the value field can expect input as object.
CurrencyTO:
field -> amount
field -> Symbol
field -> formattedAmount
The implementation to save the column value in DB is as follows:
JacksonJsonCodec<CurrencyTO> jacksonJsonCodec = new JacksonJsonCodec<>(CurrencyTO.class);
appEncodedValue.setValue(jacksonJsonCodec.format(CurrencyTO.getValue()));
CurrencyTo is extending TranserObject which has following attributes as well.
If I see in DB I am seeing the following results:
"value": "'{\"serviceResult\":{\"messagesResult\":[]},\"attributeNames\":[\"amount\",\"isoCode\",\"symbol\",\"decimalValue\",\"formattedAmount\"],\"metadata\":null,\"this\":null,\"amount\":\"45\",\"isoCode\":\"USD\",\"symbol\":\"$\",\"decimalValue\":2.0,\"formattedAmount\":null}'"
The result added the serviceResult, messageResult, metadata and some \ characters as well.
The Expected Result Should be similar as following in DB
"value": {
"amount": 90,
"Symbol": "$",
"formattedAmount" : "90.00"
}
The Reference I followed for implementation is:
custom_codecs

MongoDB - strange behaviour of query

I have this two documents in my mongoDB database:
db.DocumentFile.find().pretty()
{
"_id" : ObjectId("587f39910cc0fec092bdb10c"),
"_class" : "com.smartinnotec.legalprojectmanagement.dao.domain.DocumentFile",
"fileName" : "DocumentFile1",
"ending" : "jpg",
"projectId" : "587f39910cc0fec092bdb10b",
"active" : true,
"userIdBlackList" : [
"587f39910cc0fec092bdb10a"
]
}
{
"_id" : ObjectId("587f39910cc0fec092bdb10d"),
"_class" : "com.smartinnotec.legalprojectmanagement.dao.domain.DocumentFile",
"fileName" : "DocumentFile2",
"ending" : "jpg",
"projectId" : "587f39910cc0fec092bdb10b",
"active" : true,
"userIdBlackList" : [ ]
}
I have this code in order to get amount of query:
final Query query = new Query();
query.addCriteria(Criteria.where("‌​userIdBlackList").nin(userId));
final Long amount = mongoTemplate.count(query, DocumentFile.class);
return amount.intValue();
The amount is 2 in this case what is wrong - it should be 1.
The query in Query object looks like this:
Query: { "‌​userIdBlackList" : { "$nin" : [ "587f39910cc0fec092bdb10a"]}}
If I copy this query and made a query for the mongodb console like this:
db.DocumentFile.find({ "‌​userIdBlackList" : { "$nin" : [ "587f39910cc0fec092bdb10a"]}}).pretty()
I get an amount of two, what if wrong because one document includes 587f39910cc0fec092bdb10a in userIdBlackList -> it should be one.
With this query command:
db.DocumentFile.find({userIdBlackList: { "$nin": ["587f39910cc0fec092bdb10a"] } }).pretty();
I get the right result, I am really confused at the moment.
Does anyone have any idea?
Maybe the problem ist that one time userIdBlackList is with quotation mark ("userIdBlackList") and the other time it isn't.
I think the problem is with the unintentional formatting picked up for "userIdBlackList". Your string is interpreted with non printing characters in the "??userIdBlackList" for all your search queries. I see little transparent square boxes when I copy your queries to mongo shell.
That tells me their is some encoding issue. Clear that formatting and see if that helps you.
Both $ne and $nin should work!

How to update a partial of nested document in mongoDB using java

Here is my document :
{ "_id" : ObjectId("5495cfcaec1e18b48015bba3"),
"Type" : "1",
"DomainSize" : "60",
"Metadata" : { "visit" : "3550",
"website" : "1",
"Specifics" : { "Size:" : "2",
"Type:" : "Janes",
"Closure Type:" : "Slip-On"},
"cat" : "2",
"function" : "6"},
"rate" : " 95.5% "}
I want to update few keys from Metadata which I don't know in advance.
My input is a Map of keys and values that exist inside the Metadata list.
I'm wrapping up the given map with another Map that the key is "Metadata" and the value the given map.
Map<String,Map<String,String>> metadata =new HashMap();
metadata.put("Metadata", values);
So I'm ending up with a
<"Metadata", Map<Key,Value>>
Then I used the following:
m_collection.update(new BasicDBObject("_id",id) , new BasicDBObject("$set", new BasicDBObject(metadata)));
The record update the existing keys inside the nested map adding '[]' to each value and deleting all the keys that are not been update.
For an example the given map is {'visit': '3558' , 'website' : '20'}.
After an updated I'm ending up with:
{ "_id" : ObjectId("5495cfcaec1e18b48015bba3"),
"Type" : "1",
"DomainSize" : "60",
"Metadata" : { "visit" : ["3558"],
"website" : ["20"]},
"rate" : " 95.5% "}
What did I do wrong?
You're calling $set on "metadata" which discards whatever is there and sets the new value with whatever you pass in. If you only want to partially update a document like that that, you'll either have to pass a complete document to reflect the new state or just issue $set updates: one for each field to change.
You need to use the dotted notation in the field names used for $set
See https://docs.mongodb.org/manual/tutorial/modify-documents/

MongoDB Java Driver: Multiple Date query

I am trying to create a query using MongoDB Java Driver as part of an aggregation command. Currently I allow a date range or an array of specific dates as an argument. eg
<date>
<start>2013-12-10 00:00:00.000</start>
<end>2013-12-12 23:59:59.999</end>
</date>
or
<date>
<specificDates>2013-12-10 00:00:00.000,2013-12-13 00:00:00.000</specificDates>
</date>
The date range query works fine, I parse and convert the xml into a DBObject that produces the following query in mongo;
{ "$match" : { "d" : { "$gte" : { "$date" : "2013-10-01T00:00:00.000Z"} , "$lt" : { "$date" : "2013-10-04T00:00:00.000Z"}}}}
For the specificDates I want to return only results that occur between 00:00:00.000 on the given day and 00:00:00.000 of the next day. From my pretty basic knowledge of mongo querys i had hoped to do a similar $match as the date range, but have it use $in on an array of date ranges similar to the following;
{ "$match" : { "d" : { "$in" : [ { "$gte" : { "$date" : "2013-10-01T00:00:00.000Z"} , "$lt" : { "$date" : "2013-10-02T00:00:00.000Z"}} , { "$gte" : { "$date" : "2013-10-03T00:00:00.000Z"} , "$lt" : { "$date" : "2013-10-04T00:00:00.000Z"}}]}}}
The above query fails to return any results. I have noticed that $in is not listed in the mongodb manual under the Mongo Aggregation Framework section, but its not throwing any kind of errors that I would have expected for an unsupported operation.
I think the issue may come from this line in the MongoDB Manual;
If the field holds an array, then the $in operator selects the documents whose field holds an array that contains at least one element that matches a value in the specified array (e.g. , , etc.)
In my collection the date isn't stored in an array, I suppose I could store it in the collections in an single element array? (Actually, decided to try this quickly before I posted, no documents returned when the date entry in the document is stored in a single element array)
Document entry example
{ "_id" : ObjectId("52aea5b0065991de1a56d5b0"), "d" : ISODate("2013-12-15T00:00:11.088Z"), "t" : 1501824, "s" : 0, "e" : 601, "tld" : "uk", "y" : "domain:check", "n" : "removed.co.uk" }
Is anyone able to give me some advice as to how I should do this query? Thank you.
EDIT: I left the Java tag here in case anyone needs my DBObject creation code, though it shouldn't be necessary as the queries posted have been generated by my build.
EDIT2: So as Alan Spencer pointed out I should be using $or rather than $in, a working $or function is below (ignore the different formatting like the use of ISODate(), its just copy pasted from the mongo shell rather than getting output from my program)
{ $match : { $or : [ { d : { $gte : ISODate("2013-10-01T00:00:00.000Z"), $lt : ISODate("2013-10-02T00:00:00.000Z") } }, { d : { $gte : ISODate("2013-10-03T00:00:00.000Z"), $lt : ISODate("2013-10-04T00:00:00.000Z") } } ] } }
I think you're inverting the meaning of the $in.
$in is used to match exactly against a list of possible values, like
{"color":{"$in": ["red","green","blue"]}}
For your use case, you are trying to match if it satisfies the first or second, etc. So, you can use $or - http://docs.mongodb.org/manual/reference/operator/query/or/
{ "$match" : { "d" : { "$or" : [ { "$gte" : { "$date" : "2013-10-01T00:00:00.000Z"} , "$lt" : { "$date" : "2013-10-02T00:00:00.000Z"}} , { "$gte" : { "$date" : "2013-10-03T00:00:00.000Z"} , "$lt" : { "$date" : "2013-10-04T00:00:00.000Z"}}]}}}

How to loop through JSON parameters in android

suppose I have a JSON that prints out
{"_id" :"4e3f2c6659f25a0f8400000b",
"confirmation_code":"TWLNX8BT",
"confirmed" :true,
"created_at" :"2011-08-08T00:23:02+00:00",
"email_address" :"dd5dc43ea6bf12ec604b0a7025b94105d419616b",
"first_name" :"sean",
"invites" :[],
"last_name" :"pan",
"raw_email_address":null,
**"tracking_users" :[{
"_id" :"4e407f0659f25a1ce9000007",
"active" :true,
"first_name":"Sean",
"last_name" :"Pan",
"user_id" :"4e3da65e59f25a3956000005"
},{
"_id" :"4e407f7a59f25a1d19000007",
"active" :true,
"first_name":"Sean",
"last_name" :"Pan",
"user_id" :"4e3da65e59f25a3956000005"
},{
"_id" :"4e4085c959f25a204b000004",
"active" :true,
"first_name":"Sean",
"last_name" :"Pan",
"user_id" :"4e3da65e59f25a3956000005"
}],
"updated_at" :"2011-08-08T06:44:31+00:00",
"user_id" :137141}**
in the tracking users part I have three "different" (they're the same for testing purposes) JSON strings within the original JSON. How do I go through the inner parameter (user_id[0]),(user_id[1]),(user_id[2])... of tracking_users in a for loop for android?
I am turning my JSON into a string and then using
obj = new org.json.JSONObject(response) to change it into an object then I use
String trackingusers=obj.getString("tracking_users") to get the three objects in the tracking_users variable.
Thanks
Get tracking_users as JSONArray, then loop them as JSONObject, and with the JSONObject, you can get it's properties, try this:
JSONArray tracking_users = obj.getJSONArray("tracking_users");
for (int i = 0; i < tracking_users.length(); i++) {
JSONObject user = tracking_users.getJSONObject(i);
String _id = user.getString("_id");
and etc..
}
Use getJSONArray("tracking_users") and process each item in the array as an JSONObject.
JSON is composed from Objects and Array of objects. The whole result string is an object. So you loaded it fine. After that, you have to process tracking_users as Array of Objects. So use:
JSONAeeay users = obj.getJSONArray("tracking_users");
and with this, you can cycle through the objects:
int users_count = users.length();
for (int i=0; i<users_count; i++)
{
users.getJSONObject(i)
}

Categories