Index on Realm Object is compound index of properties or distinct indexes for each property - swift

I use 'RealmSwift' to create a Realm Database in my app. Consider a subclass of 'Object' that I use to be 'ClassA'. The 'ClassA' and its properties can be simply described as below(avoiding actual code for brevity):
ClassA: Object
-prop1
-prop2
-prop3
-prop4
-prop5
-prop6
I want to have to two indexes on the 'ClassA'. To be specific I want each index to be a compound index. Lets call the two Indexes as 'Index1' & 'Index2'. And by compound I mean an Index can have multiple properties. So lets define the two Indexes as below:
Index1: prop1, prop2, prop6
Index2: prop3, prop4, prop5
I need these compound indexes, in order to have faster fetches, in case I have the values for those particular properties. This is of critical importance for my application.
Providing indexes on Real Objects using 'RealmSwift' is done by overriding Object.indexedProperties() by returning an array of String containing the names of properties we want to index.
I want to know if this will create a separate index for each property or a single compound index for all the properties.

AS I understand the documentation Object.indexedProperties() will create an index for each property that you return, but no compound index.
What you can do to get around this is to create new properties on your objects which combine the properties you want to use for your compound index.
Example:
Create a new property indexProp126 by concatenating prop1, prop2 and prop6 to a String (just as an example, there are probably more efficient ways like hashes etc. depending on what the type and content of those properties really is) and use this as the index then.

Related

Can I store documents and key-value pairs in the same DynamoDB instance?

This is probably an obvious question, but I'm not seeing it in Amazon's documentation.
Can I store documents and key-value pairs in the same DynamoDB instance? Or can an instance only have one type?
I also don't see how to specify the object type when writing an item.
The wording is confusing. The primary keys do need to be one Data type.
DynamoDB supports many different data types for attributes within a
table. They can be categorized as follows:
Scalar Types – A scalar type can represent exactly one value. The scalar types are number, string, binary, Boolean, and null.
Document Types – A document type can represent a complex structure with nested attributes—such as you would find in a JSON document. The
document types are list and map.
Set Types – A set type can represent multiple scalar values. The set types are string set, number set, and binary set.
When you create a table or a secondary index, you must specify the
names and data types of each primary key attribute (partition key and
sort key). Furthermore, each primary key attribute must be defined as
type string, number, or binary.
DynamoDB is a NoSQL database and is schemaless. This means that, other
than the primary key attributes, you don't have to define any
attributes or data types when you create tables. By comparison,
relational databases require you to define the names and data types of
each column when you create a table.
https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/HowItWorks.NamingRulesDataTypes.html

Is there a way of allowing an end-user to modify enumeration values once application is released?

I am just starting out with CodeFluent and beginning to really like it. My question is: I set a property of an entity to enumeration. How can I allow an end-user to add extra values (that are stored afterwards as additional choices) to an enumeration? Or should I use another entity to store those values/choices instead?
For instance: let's say I have a product and a producttype. My producttype is an enumeration (frozen, fresh, seasonal), and down the road, the user wants additional types (i.e.: organic, stationary). Should those be enumeration values or a separate entity?
If a separate entity.....I'm not really sure how I define the relationship (1 to 1, 1 to many - i.e. 1 producttype can have many products)?
You can't add values to an enum at runtime, that's impossible in .NET, so it's also impossible with CodeFluent.
So, you want to create another entity that will store the list of enums. That would be a 1:M relation. This is how you would layout that relation:
Each enumeration value would be a row in the ProductType table. With CodeFluent, you can declare "instances" for an entity that will become rows in the final table, so here, you can declare your initial enum values using instance, so use the instance grid on the ProductType entity, and add instances:
Note in this case, maybe you want to create the ProductType's Id property as an int without identity (if you don't want those enum int values generated by the database).

entity framework wrong order of child object after some child objects detached

my problem is after first child object detached and then i add another child object to my parentObj the order of attached child is not correct
, my code look like this:
parentObj= new TparentObj();
firstChildObj=new Tchild1();
secondChildObj= new Tchild1();
thirdChildObj=new Tchild1();
parentObj.Tchild1.add(firstChildObj);
parentObj.Tchild1.add(secondChildObj);
// now parentObj.Tchild1.first()==firstChildObj return true
///then for some reason
parentObj.Tchild1.remove(firstChildObj);
db.Entry(firstChildObj).State = EntityState.Detached;
// now i add third childObj
parentObj.Tchild1.add(thirdChildObj);
//// now parentObj.Tchild1.first()==thirdChildObj return true!!
after saved db the result in database is Correct;
but how can i get list of childObj in order they added?
Entity Framework by default uses HashSets for its collections. HashSet doesn't take ordering into account.
You shouldn't rely on the ordering of elements for it. The current implementation seems (as you are experiencing) to add the element on the first unused position (in your case, the removed one), but this is an implementation detail and you shouldn't rely on it.
About HashSet, the MSDN says about it (bold is mine):
The HashSet class provides high-performance set operations. A set is a collection that contains no duplicate elements, and whose elements are in no particular order.
and
A HashSet collection is not sorted and cannot contain duplicate elements. If order or element duplication is more important than performance for your application, consider using the List class together with the Sort method.

Grouping list of objects based on variable attributes of object in java

I need to do group by on list of objects based multiple attributes in the object.
like lets say there is a student object
with attributes name,number,state,city,marks
now i need to do group by on it based on multiple keys,
like
it cab be state,city or state or name,state,city or marks,count(*)
Please let me know the best option to do it.
the possible options i have are.
1) using of Nested maps
2) using multimap with composite key
3) using ArrayTable.
Seems like just do a list per criteria. Otherwise I might create an Enum that implements Predicate and create a Multimap with the enum as the key.

Access the property used in mapping entity to a table in EFv4

When we have two entities in EFv4 EDM diagram and only one table for both in the database (for instance, having table Documents and entities Invoice and Qoute), table Documents having documentTypeId column as a discriminator and set this column as a discriminator in the EDM (in Table mappings), how do we read the value of this property in our code?
We cannot assign values to it because EF does it for us under the hood (based on what we entered in Table mappings for condition) but somehow I don't get it why we are also not allowed to read it.
Imo this property is already mapped so you can't map it again. It is used to determine type of materialized entity. Why do you need such column. Usually it is enough to use is operator like:
var document = context.Documents.GetById(id);
if (document is Invoice)
{
...
}
If you only need to select subtypes you can use OfType extension method like:
var invoices = context.Documents.OfType<Invoice>().ToList();
You also don't need to set this value when adding new entity because you are adding subtype - Invoice or Quote.
Edit:
As I understand from your comment you don't need this information in query. In such case you don't need to map it. Simply use partial class of your entity and add custom property which will return your string. Sound like stupid solution but actually it would be the easiest one.
Discriminator column should be part of mapping metadata so in case of T4 template generating your entities, it could be possible to update the template so it generate such property for you.
You may want to use a single-table inheritance hierarchy, as described here.
That way, you could have an abstract Document class that includes a DocumentTypeId column. Invoices and Quotes would extend this class, but specify certain DocumentTypeId filters. However, because the original class has a DocumentTypeId column, they would each have that column as well.
Another advantage to this approach is that you could create utility methods that can act on any Document, and you could pass any Invoice or Quote to these methods.