Is there anyone who had noted that Couchbase changes the numerical value of a property, over a certain limit, when recording a Json document?
Here is an example. For this test, I use the live input via the couchbase web interface.
The property "inputValue" corresponds to the value entered in the property "valueAfterSave" before clicking the save button.
The property "valueAfterSave" corresponds to the value after the save.
To a number with 16 digits, it's good:
{
"inputValue": "1234567890123456",
"valueAfterSave": 1234567890123456
}
But from 17 digits, the system begins to change the value:
{
"inputValue": "12345678901234567",
"valueAfterSave": 12345678901234568
}
or
{
"inputValue": "12345678901234599",
"valueAfterSave": 12345678901234600
}
or
{
"inputValue": "12345678901234567890",
"valueAfterSave": 12345678901234567000
}
Just out of curiosity with 40 digits
{
"inputValue": "1234567890123456789012345678901234567890",
"valueAfterSave": 1.234567890123457e+39
}
This behavior is specified somewhere? Is there a way to change it ?.
There is the solution through String values but I admit that I'm curious.
I use Couchbase Server 2.1.0 on Windows 7 Pro 32-bit platform.
Tugdual Grall, technical evangelist at Couhbase, brought me the answer.
This is due to the behavior of JavaScript when displaying such values as evidenced by the following test with NodeJS:
$ node
> console.log(12345678901234567890)
12345678901234567000
On the other hand, the value returned by the Java API is correct (12345678901234567890 in our example). It is just the console which shows this difference.
If you modify the document, through the web administration console, it is the modified value which will be saved.
So be careful with the use of the administration Console when we handle this type of data.
Tug thank you.
Related
I'm trying to understand how to interpret data from a SUPL* messages containing a wcdmaCellInformation. I've captured the data from my handset, the relevant section looks like this:
locationId: LocationId ::= {
cellInfo: WcdmaCellInformation ::= {
refMCC: 204
refMNC: 8
refUC: 4247339
}
status: 1
}
I'm trying to look up this cell information in the mozilla location services data. I've downloaded the data from https://location.services.mozilla.com/downloads and extracted it.
I can easily find matches for the refMCC (mobile country code, 204 is Netherlands) and refMNC (8 is KPN), but I'm stuck on finding the right cell in the MLS data.
If I grep for the refUC I only find a few lines from different countries, like this:
GSM,724,6,2044,10333,,30.5240236,50.4392184,0,1,1,1424733937,1634217543,
LTE,250,1,11264,84247339,11,47.8775878,56.6526018,449,19,1,1462207606,1630887268,
Is there some kind of step I'm missing to be able to do a lookup from the refUC to the cell id?
It turns out that for some reason, there's an off-by-one either on the side of Mozilla Location Services, or on the side of the SET doing the request.
Subtracting one from the refUC seems to consistently find cellular base stations that are very close to where I actually am. Maybe MLS stores the IDs zero-based, while the SET uses 1-based IDs.
Some Background:
I use Lists a lot for a Google Action with a NodeJS fulfillment backend. The Action is primarily Voice-based. The reason for using List is that I can encode information in List's key and use it later to make a decision. Another reason is that Google Assistant will try to fuzzy match the user's input with the Title of the List's items to find the closest matched option. This is where thing's get a bit hard for me. Consider the following example:
{
JSON.stringify(SOME_OBJECT): {
title: 'Yes'
},
JSON.stringify(ANOTHER_OBJECT): {
title: 'No'
}
}
Now if I say Yes / No, I can get the user's choice and do something with information stored as stringified JSON in the choice's Key.
But, the users may say Sure or Yup or OK as they basically mean the same thing as saying Yes. But as those words don't match Yes, Google Assistant will ignore the "Yes" option. But all of these words belong to the smalltalk.confirmation.yes built-in intent. So, if I could use this intent instead of hardcoding the string Yes then I would be able to capture all of the inputs that mean Yes.
I know I could do this with a Synonyms list or Confirmation intent. But they also have some problems.
Using Synonyms would require me finding every word which is similar. Besides, I would also need to localize these synonyms to all the supported language.
With Confirmation intent, I won't be able to show some information to the user before asking them to choose an option. Besides, it also doesn't support encoding the options as I can do in List's key.
So, List is a good choice for me in this case.
So, is there any way to leverage the built-in intents for this purpose? What do you do in this situation?
TLDR: What is request.resource.data.size() counting in the firestore rules when writing, say, some booleans and a nested Object to a document? Not sure what the docs mean by "entries in the map" (https://firebase.google.com/docs/reference/rules/rules.firestore.Resource#data, https://firebase.google.com/docs/reference/rules/rules.Map) and my assumptions appear to be wrong when testing in the rules simulator (similar problem with request.resource.data.keys().size()).
Longer version: Running into a problem in Firestore rules where not being able to update data as expected (despite similar tests working in the rules simulator). Have narrowed down the problem to point where can see that it is a rule checking for request.resource.data.size() equaling a certain number.
An example of the data being passed to the firestore update function looks like
Object {
"parentObj": Object {
"nestedObj": Object {
"key1": Timestamp {
"nanoseconds": 998000000,
"seconds": 1536498767,
},
},
},
"otherKey": true,
}
where the timestamp is generated via firebase.firestore.Timestamp.now().
This appears to work fine in the rules simulator, but not for the actual data when doing
let obj = {}
obj.otherKey = true
// since want to set object key name dynamically as nestedObj value,
// see https://stackoverflow.com/a/47296152/8236733
obj.parentObj = {} // needed for adding nested dynamic keys
obj.parentObj[nestedObj] = {
key1: fb.firestore.Timestamp.now()
}
firebase.firestore.collection('mycollection')
.doc('mydoc')
.update(obj)
Among some other rules, I use the rule request.resource.data.size() == 2 and this appears to be the rules that causes a permission denied error (since commenting out this rules get things working again). Would think that since the object is being passed with 2 (top-level) keys, then request.resource.data.size()=2, but this is apparently not the case (nor is it the number of keys total in the passed object) (similar problem with request.resource.data.keys().size()). So there's a long example to a short question. Would be very helpful if someone could clarify for me what is going wrong here.
From my last communications with firebase support around a month ago - there were issues with request.resource.data.size() and timestamp based security rules for queries.
I was also told that request.resource.data.size() is the size of the document AFTER a successful write. So if you're writing 2 additional keys to a document with 4 keys, that value you should be checking against is 6, not 2.
Having said all that - I am still having problems with request.resource.data.size() and any alternatives such as request.resource.size() which seems to be used in this documentation
https://firebase.google.com/docs/firestore/solutions/role-based-access
I also have some places in my security rules where it seems to work. I personally don't know why that is though.
Been struggling with that for a few hours and I see now that the doc on Firebase is clear: "the request.resource variable contains the future state of the document". So with ALL the fields, not only the ones being sent.
https://firebase.google.com/docs/firestore/security/rules-conditions#data_validation.
But there is actually another way to ONLY count the number of fields being sent with request.writeFields.size(). The property writeFields is a table with all the incoming fields.
Beware: writeFields is deprecated and may stop working anytime, but I have not found any replacement.
EDIT: writeFields apparently does not work in the simulator anymore...
I'm trying to create an RHQ plugin to gather some measurements. It seems relativity easy to create a plugin that return a value for the present moment. However, I need to collect these measurements from files. These files are created on a schedule, for example one per hour, but they contain much finer measurements, for example a measurement for every minute. The file may look something like below:
18:00 20
18:01 42
18:02 39
...
18:58 12
18:59 15
Is it possible to create a RHQ plugin that can return many values with timestamps for a measurement?
I think you can within org.rhq.core.pluginapi.measurement.MeasurementFacet#getValues return as many values as you want within the MeasurementReport.
So basically open the file, seek to the last known position (if the file is always appended to), read from there and for each line you go
MeasurementData data = new MeasurementDataNumeric(timeInFile, request, valueFromFile);
report.add(data);
Of course alerting on this (historical) data is sort of questionable, as if you only read the file one hour later, the alert can not be retroactively fired at the time the bad value happened :->
Yes it is surely possible .
#Override
public void getValues(MeasurementReport report, Set<MeasurementScheduleRequest> metrics) throws Exception {
for (MeasurementScheduleRequest request : metrics) {
Double result = SomeReadUtilClass.readValueFromFile();
MeasurementData data = new MeasurementDataNumeric(request, result)
report.addData(data );
}
}
SomeReadUtilClass is a utility class to read the file and readValueFromFile is the function, you can write you login to read the value from file.
result is the Double variable that is more important, this result value you can calculate from database or read file. And then this result value you have to provide to MeasurementDataNumeric function MeasurementDataNumeric(request, result));
I'm using a plugin and want to perform an action based on the records statuscode value. I've seen online that you can use entity.FormattedValues["statuscode"] to get values from option sets but when try it I get an error saying "The given key was not present in the dictionary".
I know this can happen when the plugin cant find the change for the field you're looking for, but i've already checked that this does exist using entity.Contains("statuscode") and it passes by that fine but still hits this error.
Can anyone help me figure out why its failing?
Thanks
I've not seen the entity.FormattedValues before.
I usually use the entity.Attributes, e.g. entity.Attributes["statuscode"].
MSDN
Edit
Crm wraps many of the values in objects which hold additional information, in this case statuscode uses the OptionSetValue, so to get the value you need to:
((OptionSetValue)entity.Attributes["statuscode"]).Value
This will return a number, as this is the underlying value in Crm.
If you open up the customisation options in Crm, you will usually (some system fields are locked down) be able to see the label and value for each option.
If you need the label, you could either do some hardcoding based on the information in Crm.
Or you could retrieve it from the metadata services as described here.
To avoid your error, you need to check the collection you wish to use (rather than the Attributes collection):
if (entity.FormattedValues.Contains("statuscode")){
var myStatusCode = entity.FormattedValues["statuscode"];
}
However although the SDK fails to confirm this, I suspect that FormattedValues are only ever present for numeric or currency attributes. (Part-speculation on my part though).
entity.FormattedValues work only for string display value.
For example you have an optionset with display names as 1, 2, 3,
The above statement do not recognize these values because those are integers. If You have seen the exact defintion of formatted values in the below link
http://msdn.microsoft.com/en-in/library/microsoft.xrm.sdk.formattedvaluecollection.aspx
you will find this statement is valid for only string display values. If you try to use this statement with Integer values it will throw key not found in dictionary exception.
So try to avoid this statement for retrieving integer display name optionset in your code.
Try this
string Title = (bool)entity.Attributes.Contains("title") ? entity.FormattedValues["title"].ToString() : "";
When you are talking about Option set, you have value and label. What this will give you is the label. '?' will make sure that the null value is never passed.