How to create an embeddedlist with Class type? - orientdb

I'm using OrientDB 3.0.1
I created an embeddelist property using:
CREATE PROPERTY MyClass.property1 EMBEDDEDLIST
And everything works fine (reading, writing) using sql.
But, I want an embeddedlist of only documents of certain type, what I want is to do something like this:
CREATE PROPERTY MyClass.property2 EMBEDDEDLIST AnotherClass
And then I want to do this:
insert into MyClass content { "property2": [{ "#Class":"AnotherClass"...},{"#Class":"AnotherClass"...}]}
I get this error:
The field 'MyClass.property2' has been declared as EMBEDDEDLIST but an incompatible type is used
So, how can I force/validate that my embeddedList only accepts documents of a specific Class? Maybe using a Hook?
Update: it works now in Orient 3.0.2 (Thanks Luigi!) here is the solution:
create class OneClass extends V;
create property OneClass.myList embeddedlist Coordinates;
insert into OneClass set myList = [
{
"#class": "Coordinates",
"latitude": 6511,
"longitude": 3
},
{
"#class": "Coordinates",
"latitude": 6518,
"longitude": 3
}
];

It is a bug in v 3.0.1 and is already fixed in v 3.0.2.

Related

Increase value of a field inside an array of element

I have documents that has the following structure in my collection:
{
"_id": "1234566780",
"arrayField": [
{
"id": "1",
"count": 3
},
{
"id": "2",
"count": 5
}
]
}
I want to have a method in my CollectionRepository that increments the value of the field count by giving to the method the collection id and the field id of the elements in the arrayField.
I have the feeling that it is not possible to do it with Spring Data autogenerated queries by method names.
So I'm trying to do it with the #Query annotation, but I have no idea on how to do it, since I need to select the collection based on _id, then select the field inside the array based on id, and then increase the count by one. Any hints?
Sorry for the delay, here is a solution to your problem.
You can update a specific element of an array using arrayFilter update option. The MongoDB update operation would look like:
db.collection.update(
{"_id":"1234566780"},
{$inc:{"arrayField.$[elem].count":1}},
{arrayFilters:[{"elem.id":"2"}]}
Admiting you are using MongoDB server and MongoDB java Driver version 3.6 or greater you could use:
public void updateCollection () {
MongoCollection<Document> collection = mongoTemplate.getDb().getCollection("collection");
Bson query = new Document("_id", "1234566780");
Bson update = Updates.inc("arrayField.$[elem].count",1);
UpdateOptions updateOptions = new UpdateOptions().arrayFilters(Arrays.asList( Filters.eq("elem.id","2")));
collection.updateOne(query, update, updateOptions);
}
Indeed Spring data method signature is not likely to generate this update. What I suggest you is to extend a CustomCollectionRepository interface with your CollectionRepository. You could define this update method signature in this interface and implement it in a CustomCollectionRepositoryImpl class. Please find the part of the documentation that mention this solution.

Is it possible to query by array content?

Using the FIWARE PointOfInterest data model I would like to filter by POI category which is an array. For instance
http://130.206.118.244:1027/v2/entities?type=PointOfInterest&options=keyValues&attrs=name,category&limit=100&q=category=="311"
having as entity instances something like
{
"id": "Museum-f85a8c66d617c23d33847f8110341a29",
"type": "PointOfInterest",
"name": "The Giant Squid Centre",
"category":
[
"311"
]
},
{
"id": "Museum-611f228f42c7fbfa4bd58bad94455055",
"type": "PointOfInterest",
"name": "Museo Extremeño e Iberoamericano de Arte Contemporáneo",
"category":
[
"311"
]
},
Looking to the NGSIv2 specification it seems that works in the way you mention:
Single element, e.g. temperature==40. For an entity to match, it must contain the target property (temperature) and the target property value must be the query value (40) (or include the value, in case the target property value is an array).
I mean, in particular the part that says:
...or include the value, in case the target property value is an array.

How to push a JSON object to a nested array in a JSONB column

I need to somehow push a JSON object to a nested array of potentionally existing JSON objects - see "pages" in the below JSON snippet.
{
"session_id": "someuuid",
"visitor_ui": 1,
"pages": [
{
"datetime": "2016-08-13T19:45:40.259Z",
"duration,": 0,
"device_id": 1,
"url": {
"path": "/"
}
},
{
"datetime": "2016-08-14T19:45:40.259Z",
"duration,": 0,
"device_id": 1,
"url": {
"path": "/test"
}
},
// how can i push a new value (page) here??
]
"visit_page_count": 2
}
I'm aware of the jsonb_set(target jsonb, path text[], new_value jsonb[, create_missing boolean]) (although still finding it a bit hard to comprehend) but I guess using that, would require that I first SELECT the whole JSONB column, in order to find out how many elements inside "pages" already exists and what index to push it to using jsonb_set, right? I'm hoping theres a way in Postgres 9.5 / 9.6 to achieve the equivalent of what we know in programming languages eg. pages.push({"key": "val"}).
What would be the best and easiest way to do this with Postgresql 9.5 or 9.6?
The trick to jsonb_set() is that it modifies part of a jsonb object, but it returns the entire object. So you pass it the current value of the column and the path you want to modify ("pages" here, as a string array), then you take the existing array (my_column->'pages') and append || the new object to it. All other parts of the jsonb object remain as they were. You are effectively assigning a completely new object to the column but that is irrelevant because an UPDATE writes a new row to the physical table anyway.
UPDATE my_table
SET my_column = jsonb_set(my_column, '{pages}', my_column->'pages' || new_json, true);
The optional create_missing parameter set to true here adds the "pages" object if it does not already exist.

MongoDB - Document with different type of value

I'm very new to MongoDB, i tell you sorry for this question but i have a problem to understand how to create a document that can contain a value with different "type:
My document can contain data like this:
// Example ONE
{
"customer" : "aCustomer",
"type": "TYPE_ONE",
"value": "Value here"
}
// Example TWO
{
"customer": "aCustomer",
"type": "TYPE_TWO",
"value": {
"parameter1": "value for parameter one",
"parameter2": "value for parameter two"
}
}
// Example THREE
{
"customer": "aCustomer",
"type": "TYPE_THREE",
"value": {
"anotherParameter": "another value",
{
"someParameter": "value for some parameter",
...
}
}
}
Customer field will be even present, the type can be different (TYPE_ONE, TYPE_TWO and so on), based on the TYPE the value can be a string, an object, an array etc.
Looking this example, i should create three kind of collections (one for type) or the same collection (for example, a collection named "measurements") can contain differend kind of value on the field "value" ?
Trying some insert in my DB instance i dont get any error (i'm able to insert object, string and array on property value), but i would like to know if is the correct way...
I come from RDBMS, i'm a bit confused right now.. thanks a lot for your support.
You can find the answer here https://docs.mongodb.com/drivers/use-cases/product-catalog
MongoDB's dynamic schema means that each need not conform to the same schema.

Mongo DB and Go - using dynamic data models

I am faced with a problem where I am not sure which path to take. So I am asking it here. I have an application where there can be products and there can be metadata for a product. These metadata can be created and deleted from the front end. So let's say, today a each product has two meta data (e.g. Name, Price) then tomorrow it can be three, four or more or even less than two. So this is dynamic. I am trying to represent the data as follows
Product =
{
"_id": mongo
"Name": string
"Description": string
"BasePrice": number
"CreatedBy": user mongo _id
"CreatedAt": timestamp
"ModifiedAt": timestamp
"MetaData": BSON object (having all the keys from ProductMetadata collection and their values. e.g. {"Category": "table ware", "Material": "oak wood, copper", "Length": 5.6})
}
ProductMetadata =
{
"_id": mongo
"Name": string (e.g. - "Category" or "Material" or "Height")
"Type": string (indicating what kind of value it can hold like string/integer/array. e.g. - "string")
"CreatedAt": timestamp
"ModifiedAt": timestamp
}
As you can see this is a pure dynamic situation so having a structure at the code level which represent the model is impossible.
My problem is, how do I implement such a thing using mgo and Go lang? If I need to use reflection then can some one please point me towards a good blog/tutorial where I can get a little bit more info. Or if you think that there is a fundamental problem in the approach of modeling the data then please correct me so that it can be easily implemented using Go.
In Python, it would not be a problem to implement this. I know that. But I am confused about the Go implementation.
Please help.
Thanks in advance
If Keys for metadata are unique, why not just use a map.
meaning your Product struct looks like:
struct Product {
ID bson.ObjectId `bson:"_id,omitempty"`
Name string
Description string
... omitted other fields ...
MetaData map[string]map[string]interface{} // map of string -> map of string -> anything
}
If you can have more than one instance of a given meta data, ie: 2 categories, use a list:
struct Product {
ID bson.ObjectId `bson:"_id,omitempty"`
Name string
Description string
... omitted other fields ...
MetaData []map[string]interface{} // list of maps of string -> anything
}