Get keys From Interface - mongodb

I know the title says interface array, but that's how the data is being printed.
I have a field in mongodb called "devices" which is of type object. This object contains a bunch of random key values pairs. The keys are just randomly generated integers and the value are a string.
So I've written some code which retrieves the data from the db, after I've retrieved the data I want to get all the keys from theses objects and store them in an array and I can't seem to figure out how to do that.
First I assume my issue lies with the way I'm getting the data since I'm storing it into an interface{} and not an array. The data prints out like an array but when I change the structure to retrieve an array it comes back empty so I scrapped that idea.
Function
type Data struct {
Devices interface{} `json:"devices" bson:"devices"`
}
client := db.ConnectClient()
col := client.Database("Users").Collection("User")
var deviceIds Data
_ = col.FindOne(context.TODO(), bson.D{}).Decode(&deviceIds)
log.Print(deviceIds.Devices)
Output
2020/10/29 21:28:07 [{123456789 Plant} {456753121 Money Bringer} {798745321 Hello}]
Also I have tried changing that struct to
type Data struct {
Devices map[int]interface{} `json:"devices" bson:"devices"`
}
which gives an output of
2020/10/29 21:35:10 map[123456789:Plant 456753121:Money Bringer 798745321:Hello]
but again I don't know how to extract the keys from them

So as I just finished writing this question I figured out the map was the correct way to get my data.
Posted the question and answering it myself because I thought it would be useful for others
type Data struct {
Devices map[int]interface{} `json:"devices" bson:"devices"`
}
for key, value := range deviceIds.Devices {
fmt.Println(key, value)
}
Changing the struct to the above map and then looping through it with range worked perfectly

Related

Creating unique index in MongoDB with type integer

I want to create a simple collection that stores statistics of different devices.
Each device has a unique device id. I want to enforce the uniqueness so I thought to create a unique index for the device id field, But I didn't figured how to tell the collection that this field is of type number.
For example I can receive query with device id '0x3f', '0x0003f', '3f'... and all of them need to match to the same document.
I can parse the request before querying the DB but to me it's not sound like the right solution...
I suggest not worrying about this in Mongo, but instead trying to handle it in your application layer which is calling Mongo. For example, in JavaScript, appreciate that using any hex literal translates to the same integer value:
var i = 0x3f;
var j = 0x0003f;
if (i == 63) {
console.log("0x3f = 63");
}
if (j == 63) {
console.log("0x0003f = 63");
}
That is, just let the application marshall the hex literal into an integer value, then pass that int value to Mongo.

Mongo Go Driver is getting interface conversion error when SetSort used

I would like to change order my documents in Mongo DB using Go. I have valid json string code and i can marshal it successfully in to map[string]int. The sample of this type just like:
[{year 1}, {lastupdated -1}]. The value presents order year field ascending and lastupdated field descending. This struct is aspect of MongoDB understands. Also I'm pass this data into bson.D type. Here is my code:
if queries["order"] != nil {
var unmarshalledOrder map[string]int
json.Unmarshal(queries["order"].([]byte), &unmarshalledOrder)
docRes := make(bson.D, 0)
for field, sort := range unmarshalledOrder {
docRes = append(docRes, bson.DocElem{field, sort})
}
log.Println(docRes)
}
When I print docRes, everthing goes well. But i pass the data to options.Sort function, the function throws interface conversion: interface {} is runtime.errorString, not string panic. Is it a bug on mongo go driver or am i wrong?
Can you post the code you've written which uses the driver? Based on the use of bson.DocElem, I think you're using mgo, but mgo's Query.Sort method takes strings, not documents (https://pkg.go.dev/github.com/globalsign/mgo?tab=doc#Query.Sort).

Realm Swift - How to remove an item at a specific index position?

I am storing a simple list of id's as GUIDs in Realm, but would like the ability to delete an object at a particular index position.
So for example, I want to remove 04b8d81b9e614f1ebb6de41cb0e64432 at index position 1, how can this be achieved? Do I need to add a primary key, or is there a way to remove the item directly using the given index position?
Results<RecipeIds> <0x7fa844451800> (
[0] RecipeIds {
id = a1e28a5eef144922880945b5fcca6399;
},
[1] RecipeIds {
id = 04b8d81b9e614f1ebb6de41cb0e64432;
},
[2] RecipeIds {
id = cd0eead0dcc6403493c4f110667c34ad;
}
)
It seems like this should be a straightforward ask, but I can't find any documentation on it. Even a pointer in the right direction would do.
Results are auto-updating and you cannot directly modify them. You need to update/add/delete objects in your Realm to effect the state of your Results instance.
So you can simply grab the element you need from your Results instance, delete it from Realm and it will be removed from the Results as well.
Assuming the Results instance shown in your question is stored in a variable called recipes, you can do something like the following:
let recipeToDelete = recipes.filter("id == %#","04b8d81b9e614f1ebb6de41cb0e64432")
try! realm.write {
realm.delete(recipeToDelete)
}

How to disable sorting of return array?

I have a custom rest action like this (in a class that extends yii/rest/ActiveController):
public function actionTest()
{
return ["9" => "Nine", "1" => "one"];
}
When calling the API, the array output is in reverse order, ie:
{
"1": "One"
"9": "Nine",
}
I would like to have it in the original (expected) order...
Seems like the array was sorted somewhere after the array was returned in the action, but I can't figure out where. This only happens when the array key is an integer, an array like this is sorted as expected:
["id-9" => "Nine", "id-1" => "one"]
Have tried using an ArrayDataProvider setting 'sort' = false, but that made no difference.
Since you're exporting it as json and looking at that, from this question - Keeping dictionary keys of JSON Object in order in Objective C, the answer left by Henning Makholm says that:
In JSON objects, by definition, the order of the key-value pairs is not meaningful. The specification allows a JSON producer to permute them any way it want, even at random -- and does not require a parser to preserve the ordering. RFC 4627 says:
An object is an unordered collection of zero or more name/value pairs, where a name is a string and a value is a string, number, boolean, null, object, or array.
So json has no ordering, since it uses a dictionary as its data structure and typically dictionaries will have no implicit or explicit ordering due to the way they hash the keys for quick access.
It may be that the actual underlying representation in your program is ordered, but the json output has no such guarantee.
One way to fix this would be to move to a different data structure where order is preserved.

I would like to store the values in array list after iterating the select options , is it possible in Watir

I am trying to store the values of select list in an array variable
a = b.options.each {|option| puts option.attribute_value "value" }
Output :
IN PROGRESS
UPCOMING
FINAL
POSTPONED
CANCELLED
a.to_i
Is it possible to store all values which getting from attribute and store in An array
The element collections in Watir include the Enumerable module, which gives a lot of useful methods for iterating. In particular, it includes a map method that will perform a block on each element and collect the result in an array.
To store the value of all options, you can simply do:
total_list_values = #browser.options.map(&:value)
#=> ["IN PROGRESS", "UPCOMING", "FINAL", "POSTPONED", "CANCELLED"]
I coded it like this and its worked, posted if anyone wanted this
total_list_values = Array.new
body = #browser.options
body.options.each do |option|
total_list_values << option.value
end