({{, (RefLink[EntityStore, paclet:ref/EntityStore])["type"] 
represents an empty entity store for entities of type "type".}, {, (RefLink[EntityStore, paclet:ref/EntityStore])["type"->data]
represents an entity store for entities of type "type" with properties and values defined by data.}, {, (RefLink[EntityStore, paclet:ref/EntityStore])[{(Subscript[tspec, 1]),(Subscript[tspec, 2]),…}]
represents an entity store for entities of multiple types.}, {, EntityStore[(RefLink[RelationalDatabase, paclet:ref/RelationalDatabase])[…]]
constructs an entity store from the schema of an external database.}, {, (RefLink[EntityStore, paclet:ref/EntityStore])[{(Subscript[tspec, 1]),(Subscript[tspec, 2]),...},dbspec]
constructs an entity store by mapping table names in the database specified by dbspec to types as specified by the (Subscript[tspec, i]).}})

OpenersNotesSection(Spacer1)Details and Options

If an (RefLink[EntityStore, paclet:ref/EntityStore]) object is included in the list (RefLink[EntityStores, paclet:ref/EntityStores])[], then the entity types it contains are accessed automatically when (RefLink[Entity, paclet:ref/Entity]) is used. Unless permissions are set otherwise, its contents can be modified by assignments of the form entity[property]=value.

Data in an (RefLink[EntityStore, paclet:ref/EntityStore]) object can be accessed directly using store[obj,"property"], where obj is an (RefLink[Entity, paclet:ref/Entity]), (RefLink[EntityClass, paclet:ref/EntityClass]), (RefLink[EntityProperty, paclet:ref/EntityProperty]), or (RefLink[EntityPropertyClass, paclet:ref/EntityPropertyClass]) object.

In (RefLink[EntityStore, paclet:ref/EntityStore])[{(Subscript[tspec, 1]),(Subscript[tspec, 2]),…}], each of the (Subscript[tspec, i]) can be either "(Subscript[type, i])" or "(Subscript[type, i])"->(Subscript[data, i]).

In (RefLink[EntityStore, paclet:ref/EntityStore])["type"->data], data is an association that defines entities, properties, and values associated with the specified type.

The "Entities" element of data can give an association with properties of entities of the given type: "Entities"-><|"(Subscript[name, 1])"->(Subscript[props, 1]),…|>. The (Subscript[props, i]) give values of properties for the specified entity: <|"(Subscript[prop, a])"->(Subscript[val, 1a]),"(Subscript[prop, b])"->(Subscript[val, 1b]),…|>.

The special property "Label" can be given for any entity, specifying how it should be displayed.

The "Properties" element of data gives information on properties, such as how properties should be displayed and how property values that are not explicitly specified should be computed.

Possible entries in the data association for a given type include:

The "Properties" entry in data is of the form <|"(Subscript[prop, a])"-><|(Subscript[k, 1])->(Subscript[v, 1]),…|>,"(Subscript[prop, b])"->…,…|>. Possible entries in the association given for each property include:

With the setting "DefaultFunction"->f for a given property, f is applied to an entity to compute the value of that property if it is not specified explicitly in the "Entities" association.

Possible entries for each entity class in "EntityClasses" include:

In the association for a particular entity class, "Entities"->{"(Subscript[name, 1])","(Subscript[name, 2])",…} gives an explicit list of entities in the entity class. "Entities"->"prop"->pred specifies that the entities in the class are those for which pred gives (RefLink[True, paclet:ref/True]) when applied to the value of the property prop.

Possible entries for each property class in "PropertyClasses" include:

In the form (RefLink[EntityStore, paclet:ref/EntityStore])[{"(Subscript[type, 1])"->(Subscript[meta, 1]),"(Subscript[type, 2])"->(Subscript[meta, 2]),…},databasespec], the (Subscript[meta, i]) can have the following forms:

In the form (RefLink[EntityStore, paclet:ref/EntityStore])[{…,"(Subscript[type, i])"->class,…},…], class can be any of the heads: (RefLink[EntityClass, paclet:ref/EntityClass]), (RefLink[FilteredEntityClass, paclet:ref/FilteredEntityClass]), (RefLink[ExtendedEntityClass, paclet:ref/ExtendedEntityClass]), (RefLink[SampledEntityClass, paclet:ref/SampledEntityClass]), (RefLink[SortedEntityClass, paclet:ref/SortedEntityClass]), (RefLink[AggregatedEntityClass, paclet:ref/AggregatedEntityClass]), (RefLink[CombinedEntityClass, paclet:ref/CombinedEntityClass]).

In relational-databases-backed entity stores, the structure of the first argument of (RefLink[EntityStore, paclet:ref/EntityStore]) has the form <|"Types"-><|"(Subscript[type, 1])"-><|…|>,"(Subscript[type, 2])"-><|…|>,…|>|>, where each association on the right-hand side of each "(Subscript[type, i])" can have the following keys:

In relational databases, properties come in three flavors: columns on the original database, computed properties or relations.

Column properties are defined with an association containing:

Computed properties are defined with an association containing:

Relations properties are properties that take (RefLink[Entity, paclet:ref/Entity]) or (RefLink[EntityClass, paclet:ref/EntityClass]) values referencing types in the (RefLink[EntityStore, paclet:ref/EntityStore]); they are defined by an association containing:

"EntityTypeMapping" has the same specification as (RefLink[CombinedEntityClass, paclet:ref/CombinedEntityClass]) and can take values of the form:

In relational-database-backed entity stores, formatting using "Label" properties is disabled to ensure that all calls to (RefLink[EntityValue, paclet:ref/EntityValue]) and (RefLink[EntityList, paclet:ref/EntityList]) perform a single call to the database.

OpenersPrimaryExamplesSection(Spacer1)Examples  (15)

OpenersExampleSection0(Spacer1)Basic Examples  (3)

Create an entity store for entities with type "t" named "e1" and "e2", each with properties "p1" and "p2":

store=EntityStore["t"-><|
"Entities"-><|
"e1"-><|"p1"->17,"p2"->59|>,
"e2"-><|"p1"->27,"p2"->288|>
|>
|>]

Register this entity store in the global list of entity stores:

EntityRegister[store]

Now property values for an entity are automatically looked up in the entity store:

Entity["t","e1"]["p1"]

Get the list of entities of the specified type:

EntityList["t"]

Find entities whose value of the property "p2" is greater than 100:

EntityClass["t","p2"->GreaterThan[100]]//EntityList

Unregister the entity store:

EntityUnregister["t"]

To connect to an external database, construct a (RefLink[RelationalDatabase, paclet:ref/RelationalDatabase]) object:

schema=RelationalDatabase[FindFile["ExampleData/ecommerce-database.sqlite"]]

Construct an (RefLink[EntityStore, paclet:ref/EntityStore]) from the (RefLink[RelationalDatabase, paclet:ref/RelationalDatabase]) object:

store = EntityStore[schema]

Register the (RefLink[EntityStore, paclet:ref/EntityStore]):

EntityRegister[store]

Perform a query:

EntityValue["offices", "city"]

Unregister the entity store:

EntityUnregister[store]

Construct a database-backed (RefLink[EntityStore, paclet:ref/EntityStore]) with a subset of the original tables in the database:

EntityStore[{"offices"}, DatabaseReference[FindFile["ExampleData/ecommerce-database.sqlite"]]]

EntityStore[]

OpenersExampleSection1(Spacer1)Scope  (10)

OpenersExampleSubsection0(Spacer1)Basic Uses  (4)

Create an entity store with a computed property "p3" and entity and property classes:

store=EntityStore["MyType"-><|
"Label"->"my type",
"LabelPlural"->"my type entities",
"Entities"-><|
"e1"-><|"p1"->1,"p2"->2,"Label"->"E1"|>,
"e2"-><|"p1"->3,"p2"->4,"Label"->"E2"|>,
"e3"-><|"Label"->"E3"|>
|>,
"Properties"-><|
"p1"-><|"Label"->"P1"|>,
"p3"-><|"DefaultFunction"->Function[e,e["p1"]+e["p2"]],"Label"->"P3"|>
|>,
"EntityClasses"-><|
"ec1"-><|"Entities"->{"e1","e2"},"Label"->"EC1"|>,
"ec2"-><|"Entities"->{"p3"->GreaterThan[3]}|>
|>,
"PropertyClasses"-><|
"pc1"-><|"Properties"->{"p1","p3"},"Label"->"PC1"|>
|>
|>]

EntityRegister[store];

Obtain the computed value:

Entity["MyType","e2"]["p3"]

Look up the members of "ec2":

EntityList[EntityClass["MyType","ec2"]]

Get an (RefLink[Association, paclet:ref/Association]) of the value of all properties in "pc1" for one entity:

Entity["MyType","e1"][EntityPropertyClass["MyType","pc1"],"PropertyAssociation"]

EntityUnregister[store];

Access the entity store directly:

store[Entity["MyType","e1"],"p1"]

Values are not computed:

store[Entity["MyType","e1"],"p3"]

Access properties of an entity class:

store[EntityClass["MyType","ec1"],"Label"]

Retrieve the raw data stored for "Entities":

store[EntityClass["MyType","ec1"],"Entities"]

Create an entity store of all integers:

integerStore=EntityStore["integer"-><|
"EntityValidationFunction"->IntegerQ@*Interpreter["Integer"],
"Properties"-><|
"Factorial"-><|
"DefaultFunction"->Function[entity,entity["Value"]!]
|>,
"Value"-><|
"DefaultFunction"->Interpreter["Integer"]@*CanonicalName
|>
|>
|>]

EntityRegister[integerStore];

Get the numerical value of an entity:

Entity["integer","4"]["Value"]

Compute the factorial of the entity "4":

Entity["integer","4"]["Factorial"]

Invalid entities are rejected:

Entity["integer","abc"]["Factorial"]

Change the value of the "Factorial" of the entity "7":

Entity["integer","7"]["Factorial"]=7

This introduces an entity together with the new value into the registered entity store for "integer":

newIntegerStore=Entity["integer"]["EntityStore"]

newIntegerStore[Entity["integer","7"],"Factorial"]

Other entities do not have an explicit value:

newIntegerStore[Entity["integer","6"],"Factorial"]

EntityUnregister["integer"]

Define an (RefLink[EntityStore, paclet:ref/EntityStore]) containing labeled entities and entity classes:

store=EntityStore["type"-><|
"Entities"-><|"e1"-><|"Label"->"E1"|>,"e2"-><|"Label"->"E2"|>|>,
"EntityClasses"-><|"ec1"-><|"Entities"->{"e1","e2"},"Label"->"EC1"|>|>
|>];

Normally an (RefLink[EntityClass, paclet:ref/EntityClass]) behaves like the list of entities it represents. Get the "Label" for each entity in the class:

EntityRegister[store];

EntityClass["type","ec1"]["Label"]

EntityUnregister[store]

To get the "Label" of the class, access the (RefLink[EntityStore, paclet:ref/EntityStore]) directly:

store[EntityClass["type","ec1"],"Label"]

Put an entity store into the cloud:

co=CloudPut[EntityStore["t"-><|
"Entities"-><|
"e1"-><|"p1"->99,"p2"->88|>,
"e2"-><|"p1"->77,"p2"->66|>
|>
|>]]

Share the cloud object with someone who can then use the entities contained in it:

EntityRegister[CloudGet[co]];

Entity["t","e2"]["p2"]

EntityUnregister["t"]

OpenersExampleSubsection1(Spacer1)Database connectivity  (5)

Construct an (RefLink[EntityStore, paclet:ref/EntityStore]) renaming the tables:

EntityStore[{"Offices" ->"offices"}, RelationalDatabase[FindFile["ExampleData/ecommerce-database.sqlite"]]]

Construct an (RefLink[EntityStore, paclet:ref/EntityStore]) with a subset of the columns:

EntityStore[{"offices" ->{"officeCode", "city"}}, RelationalDatabase[FindFile["ExampleData/ecommerce-database.sqlite"]]]

Construct an (RefLink[EntityStore, paclet:ref/EntityStore]) renaming the columns:

EntityStore[{"offices" ->{"OfficeCode" ->"officeCode","City" -> "city"}}, RelationalDatabase[FindFile["ExampleData/ecommerce-database.sqlite"]]]

Construct an (RefLink[EntityStore, paclet:ref/EntityStore]) with computed types:

EntityStore[{"someEmployees" ->FilteredEntityClass["employees" , EntityFunction[x, StringStartsQ[x["firstName"],"L"]]]}, RelationalDatabase[FindFile["ExampleData/ecommerce-database.sqlite"]]]

Construct an (RefLink[EntityStore, paclet:ref/EntityStore]) with computed properties:

EntityStore[{"orders" ->{"orderNumber", "orderDate" -> EntityFunction[x, FromUnixTime[x["orderDate"]]]}}, RelationalDatabase[FindFile["ExampleData/ecommerce-database.sqlite"]]]

OpenersExampleSubsection2(Spacer1)Qualifiers  (1)

Specify "beehive" entities with a "Date"-qualified "Population" property:

EntityRegister[EntityStore["beehive"-><|
"Entities"-><|
"lisa"-><|
{"Population","Date"->All}->TimeSeries[{
{{2013},100000},
{{2014},200000},
{{2015},150000}
}]
|>,
"tom"-><|
{"Population","Date"->All}->TimeSeries[{
{{2013},300000},
{{2014},200000},
{{2015},200000}
}]
|>
|>,

"Properties"-><|
"Population"-><|
"DefaultFunction"->Function[ent,ent[Dated["Population",All]]["LastValue"]]
|>,
{"Population","Date"->_?DateObjectQ}-><|
"DefaultFunction"->Function[{ent,quals},
Round[ent[Dated["Population",All]][quals["Date"]]]
]
|>
|>
|>]];

Get the latest population for Lisa's beehive:

Entity["beehive","lisa"]["Population"]

Get the population for mid-2014:

Entity["beehive","lisa"]["Population","Date"->DateObject[{2014,6}]]

Use (RefLink[Dated, paclet:ref/Dated]):

Entity["beehive","lisa"][Dated["Population",2014]]

This is equivalent:

Dated[Entity["beehive","lisa"],2014]["Population"]

Get the time series:

Entity["beehive","lisa"]["Population","Date"->All]

DateListPlot[%]

The population of all beehives in 2013:

EntityClass["beehive",All][Dated["Population",2013],"EntityAssociation"]

EntityUnregister["beehive"]

OpenersExampleSection3(Spacer1)Possible Issues  (2)

In database-backed entity stores, "Label" properties are not used for formatting:

EntityRegister[EntityStore["offices" -> {"officeCode", "Label" -> "territory"}, RelationalDatabase[FindFile["ExampleData/ecommerce-database.sqlite"]]]]

EntityList["offices"]

When dealing with external databases, one might encounter a database where the primary key was not set for some tables:

EntityRegister[EntityStore[RelationalDatabase[URLDownload[CloudObject["https://www.wolframcloud.com/objects/documentation/nopk.sqlite"]]]]]

When this happens, (RefLink[EntityStore, paclet:ref/EntityStore]) will emit a message. This means that some functionality involving single entities will be disabled:

EntityList["table"]

But (RefLink[EntityValue, paclet:ref/EntityValue]) will generally keep working:

EntityValue["table", "col"]

The only way around this problem is to set the primary key constraint in the external database.

({{DocumentationFooterIconsRelatedFunction.png, ({{See Also}, {(RefLink[Entity, paclet:ref/Entity])  ▪  (RefLink[EntityRegister, paclet:ref/EntityRegister])  ▪  (RefLink[EntityStores, paclet:ref/EntityStores])  ▪  (RefLink[EntityValue, paclet:ref/EntityValue])  ▪  (RefLink[EntityProperty, paclet:ref/EntityProperty])  ▪  (RefLink[EntityClass, paclet:ref/EntityClass])  ▪  (RefLink[EntityPropertyClass, paclet:ref/EntityPropertyClass])  ▪  (RefLink[ResourceObject, paclet:ref/ResourceObject])}})}})

({{DocumentationFooterIconsRelatedGuide.png, ({{Related Guides}, {▪(RefLinkPlain[Knowledge Representation & Access, paclet:guide/KnowledgeRepresentationAndAccess])}, {▪(RefLinkPlain[Database Connectivity, paclet:guide/DatabaseConnectivity])}, {▪(RefLinkPlain[Working with Information in Relational Databases, paclet:guide/WorkingWithRelationalDatabases])}, {▪(RefLinkPlain[Entity Types, paclet:guide/EntityTypes])}, {▪(RefLinkPlain[WDF (Wolfram Data Framework), paclet:guide/WDFWolframDataFramework])}, {▪(RefLinkPlain[Wolfram Data Repository, paclet:guide/WolframDataRepository])}})}})