Creating fields in MongoDB - ruby-on-rails

I would like to change my database from SQLite to MongoDB since mongo is schema less. In SQL database i had to create multiple rows for each attribute for the same sku(a product). I have to create n number of columns since each attribute have different specifications. Now in mongo I am planning to create only one document(row) for a sku having same id. To achieve this I would like to create a field(column) for specifications like html, pdf, description, etc. Now the last field is for attributes which has different values. I would like to store it in hash.(key value pairs). Does it make sense to store all the attributes in single cell? Am I going in right direction? Someone please suggest.
EDIT:
I want something like this.
My question is, in SQL i was creating columns for each attributes like attribute 1 name, value and attribute 2 name, value. This extends the row size. Now i want to store all the attributes in hash format(as shown in the image) since MongoDB is schema less. Is it possible? And does it makes sense? Is there any better option out?

Ultimately, how you store the data should be influenced by how you intend on accessing or updating the data, but one approach would be to create an embedded attributes object within each sku/product with all attributes for that sku/product:
Based on your example:
{
"sku_id" : 14628109,
"product_name" : "TE Connectivity",
"attributes" : {
"Widhth" : [ "4", "mm" ],
"Height" : [ "56", "cm" ],
"Strain_Relief_Body_Orientation" : "straight",
"Minimum_Operating_Temperature" : [ "40" , "C" ]
}
},
{
"sku_id" : 14628110,
"product_name" : "Tuning Holder",
"attributes" : {
"Widhth" : [ "7", "mm" ],
"diametr" : [ "78", "cm" ],
"Strain_Relief_Body_Orientation" : "straight",
"Minimum_Operating_Temperature" : [ "4" , "C" ]
}
},
{
"sku_id" : 14628111,
"product_name" : "Facing Holder",
"attributes" : {
"size" : [ "56", "nos" ],
"Height" : [ "89", "cm" ],
"Strain_Relief_Body_Orientation" : "straight",
"Minimum_Operating_Temperature" : [ "56" , "C" ]
}
}

Related

Elm : How to Encode Nested objects

Model
type alias Model {
name : String
, poi_coordinates : Coordinates
}
type alias Coordinates =
{
coord_type : String
, coordinates : List Float
}
poiFormEncoder : Model -> Encode.Value
poiFormEncoder model =
Encode.object
[
( "name", Encode.string model.name )
, ( "type", Encode.string model.poi_coordinates.coord_type)
, ( "poi_coordinates", Encode.array Encode.float (Array.fromList model.poi_coordinates.coordinates) )
]
Can i ask how to encode for this data type? I have no idea , and the encoder i did gives no coordinates fill. Any help is really appreciate. The Json file format is at below
[
{
"name": "Mcd",
"coordinates": {
"type": "Point",
"coordinates": [
101.856603,
2.924
]
}
},
.
.
.
]
You can nest calls to Json.Encode.object. Each time you want a new object in the output, you need another one, e.g:
poiFormEncoder : Model -> Encode.Value
poiFormEncoder model =
Encode.object
[ ( "name", Encode.string model.name )
, ( "coordinates"
, Encode.object
[ ( "type", Encode.string model.poi_coordinates.coord_type )
, ( "coordinates", Encode.list Encode.float model.poi_coordinates.coordinates )
]
)
]
This should make sense: it is a list of (key, value) pairs, and the value should be another object.
On a side note, it will depend on your use case, but your Coordinates type looks like a prime candidate for a custom Elm type, e.g:
type Coordinates
= Point { x : Float, y : Float }
| Polar { r : Float, t : Float }
| ...
If you find you are doing a lot of checking the string type value and then dealing with the coordinates accordingly, something like this might be a much nicer structure to use internally. Of course, the best representation will depend on how you are using the type.

Multiple Joins In CouchDB

I am currently trying to figure out if CouchDB is suitable for my use-case and if so, how. I have a situation similar to the following:
First set of documents (let's call them companies):
{
"_id" : 1,
"name" : "Foo"
}
{
"_id" : 2,
"name" : "Bar"
}
{
"_id" : 3,
"name" : "Baz"
}
Second set of documents (let's call them projects):
{
"_id" : 4,
"name" : "FooProject1",
"company" : 1
}
{
"_id" : 5,
"name" : "FooProject2",
"company" : 1
}
...
{
"_id" : 100,
"name" : "BazProject2",
"company" : 3
}
Third set of documents (let's call them incidents):
{
"_id" : "300",
"project" : 4,
"description" : "...",
"cost" : 200
}
{
"_id" : "301",
"project" : 4,
"description" : "...",
"cost" : 400
}
{
"_id" : "302",
"project" : 4,
"description" : "...",
"cost" : 500
}
...
So in short every company has multiple projects, and every project can have multiple incidents. One reason I model the data is, that I come mainly from a SQL background, so the modelling may be completely unsuitable. The second reason is, that I would like to add new incidents very easily by just using the REST-API provided by couchdb. So the incidents have to be single documents.
However, I now would like to get a view that would allow me to calculate the total cost for each company. I can easily define a view using map-reduce and linked documents which get's me the total amount per project. However once I am at the project level I cannot get any further to the level of the company.
Is this possible at all using couchDb? This kind of summarising data sounds like a perfect use case for map-reduce. In SQL I would just do a three-table join, but it seems like in couchDb the best I can get is two-table joins.
As mentioned you cannot do joins in CouchDb but this isn't a limitation, this is an invitation to both think about your problems and approach them differently. The correct way to do this in CouchDb is to define data structures called for example : IncidentReference composed of :
The project id
And the company id
That way your data would look like :
{
"_id" : "301",
"project" : 4,
"description" : "...",
"cost" : 400,
"reference" : {
"projectId" : 1,
"companyId" : 2
}
}
This is just fine. Once you have that, you can play with Map/Reduce to achieve whatever you want easily. Generally speaking, you need to think about the way you are going to query your data.

CloudFormation Join in Tags

I'm running a CloudFormation template that uses the following snippet to tag various resources (this is a ELB tag, but others also exhibit this problem) I would expect this to produce a name tag of stackName-asgElb but it actually produces names such as olive-asg-asgElb-16GSCPHUFSWEN.
The stack name in this case was named olive-asg so I was expecting olive-asg-asgElb, without the -16GSCPHUFSWEN on the end.
Does anybody know where the seemingly random string on the end comes from?
CF template snippet:
Tags: [
{
Key: "Name",
Value: {
"Fn::Join": [
"-",
[
{
Ref: "AWS::StackName"
},
"asgElb"
]
]
}
}
]
That's interesting, I just tried it and I'm not able to reproduce the same results that you're seeing. It seems to be working as expected.
Here's the snippet I'm using in its entirety:
"ElasticLoadBalancer" : {
"Type" : "AWS::ElasticLoadBalancing::LoadBalancer",
"Properties" : {
"AvailabilityZones" : { "Fn::GetAZs" : "" },
"CrossZone" : "true",
"Listeners" : [ {
"LoadBalancerPort" : "80",
"InstancePort" : "80",
"Protocol" : "HTTP"
} ],
"Tags" : [
{
"Key" : "Name",
"Value" : { "Fn::Join" : [ "-", [ { "Ref" : "AWS::StackName" }, "MyELB"] ] }
}
]
}
},
The one noticeable difference I see in yours is that you're missing some of the quotes around the Tag stanza.
I feel foolish, the name tags are set correctly, I was looking at the physical IDs, not the name tags. The docs explaining how to control physical IDs are here.
Thanks to #alanwill for testing, and forcing me to go back through all the steps carefully!

Match column names to graph results in neo4j transactional REST response

A very cool feature of the neo4j transactional REST api endpoint is that you can get query results in graph format. However, I'm having trouble figuring out which node matches which column name when there are multiple nodes returned. Based on my testing the order of the nodes is not consistent with the column order.
For instance, in the example given in the documentation the query ends with
RETURN bike, p1, p2
and the response (edited) includes
"graph" : {
"nodes" : [ {
"id" : "4",
"labels" : [ "Bike" ],
"properties" : {
"weight" : 10
}
}, {
"id" : "5",
"labels" : [ "Wheel" ],
"properties" : {
"spokes" : 3
}
}, {
"id" : "6",
"labels" : [ "Wheel" ],
"properties" : {
"spokes" : 32
}
} ]
My question is, how do I know if the Wheel p1 corresponds to the node with id 5 or the node with id 6? Again, I don't think the order is guaranteed, at least as far as I can tell.
Actually, p1 and p2 are not nodes -- they are paths. In the Cypher code, one wheel is named frontWheel and the other is named backWheel.
To figure out the graph structure, you need to look at the relationships as well as the nodes in the returned graph data.
Here is another snippet from the results:
"relationships" : [ {
"id" : "0",
"type" : "HAS",
"startNode" : "4",
"endNode" : "5",
"properties" : {
"position" : 1
}
}, {
"id" : "1",
"type" : "HAS",
"startNode" : "4",
"endNode" : "6",
"properties" : {
"position" : 2
}
} ]
From the relationships data (especially startNode, endNode and the position property), you can tell that node 4 is bike, node 5 is frontWheel, and node 6 is backWheel.

can neo4j find the shortest n paths by Traversals with index?

I read the wiki api from http://docs.neo4j.org/chunked/snapshot/rest-api-traverse.html
and check my code, i can find the shortest n paths by Traversals ,and can find nodes or relationships with index. but my projects has 300M nodes ,when i find shortest n paths by Traversals ,like retionship data property Name contain 'hi' ,if i use neo4j's fiter method,it is really slow,i want use index(i created it!),code like:
{
"order" : "breadth_first",
"return_filter" : {
"body" : "position.endNode().getProperty('name').toLowerCase().contains('t')",
"language" : "javascript"
},
"prune_evaluator" : {
"body" : "position.length() > 10",
"language" : "javascript"
},
"uniqueness" : "node_global",
"relationships" : [ {
"direction" : "all",
"type" : "knows"
}, {
"direction" : "all",
"type" : "loves"
} ],
"max_depth" : 3
}
i want :
{
"order" : "breadth_first",
"return_filter" : {
"body" : "position.endNode().name:*hi*",
"language" : "javascript"
},
"prune_evaluator" : {
"body" : "position.length() > 10",
"language" : "javascript"
},
"uniqueness" : "node_global",
"relationships" : [ {
"direction" : "all",
"type" : "knows"
}, {
"direction" : "all",
"type" : "loves"
} ],
"max_depth" : 3
}
can someone help me ?
Is it slow the first time or are consecutive requests equally slow? Properties are loaded per node/relationship the first time any property is requested for that node/relationship and maybe you're seeing that performance hit.
I think that using an index would help for nodes that haven't been loaded yet, but not otherwise. Doing this in rest could be tricky in that you'd have to do index lookup before hand and pass that list into the evaluator. But that doesn't scale. Instead could write an extension for this?

Resources