Search entities using characteristic criteria

When searching for entities based on characteristic records the new Expression CharacteristicExpression should be used.

Characteristic expression

A characteristic expression can be used programmatically in the following way:

Expression characteristicExp = new CharacteristicExpression( entityProxyOfTheCharacteristic );

It can then be used in the same manner as any other BinaryExpression:

Expression expression = new EqualExpression( characteristicExp, valueExp );

The result will be all entities which have a characteristic record for the characteristic defined by the characteristicExp and with the value defined in the valueExp.

Example

We want to build a search query which searches for items which contain the value "Flour" in a record for the characteristic "Ingredient".

Characteristic ingredient = this.modelService.getCharacteristic("Ingredient"); //Characteristic with Datatype "Text"
EntityProxy characteristic = ingredient.getEntityProxy();
 
Expression characteristicExp = new CharacteristicExpression( characteristic );
Expression valueExp = new ValueExpression( "Flour" );
Expression expression = new EqualExpression( characteristicExp, valueExp );
 
SearchParameters searchParameters = new SearchParameters( DataSource.SUPPLIER, ArticleConst.ENTITY_TYPE,
expression );
EntityProxy[] searchResult = this.searchService.searchAsEntityProxies( new NullProgressMonitor(), searchParameters,
null );

We have these articles with characteristic records:

ItemIdentifier

Characteristic

Characteristic record value

Item1

Ingredient

"Salt"

Item2

Ingredient

"Flour"

Item3

Ingredient

"Egg"

Item4

BakingMaterials

"Flour"

The query above will only return Item2.

Searching for LookupValues of a characteristic

When searching for Lookup values, a LookupValueProxy has to be in the ValueExpression.

When using enumeration based lookup values the method getKey() returns the EntityProxy.

Example

We want to find all articles which have the LookupValue "Wool" in the record for the characteristic "animalIngredient".

Characteristic animalIngredients= this.modelService.getCharacteristic( "animalIngredient"); //Characteristic with Datatype "Lookup"
EntityProxy characteristic = animalIngredient.getEntityProxy();
 
LookupValue wool = ingredientLookup.getValueByKey( "Wool");
 
Expression characteristicExp = new CharacteristicExpression( characteristic );
Expression valueExp = new ValueExpression( wool.getKey() );
Expression expression = new EqualExpression( characteristicExp, valueExp );
 
 
SearchParameters searchParameters = new SearchParameters( DataSource.SUPPLIER, ArticleConst.ENTITY_TYPE,
expression );
EntityProxy[] searchResult = this.searchService.searchAsEntityProxies( new NullProgressMonitor(), searchParameters,
null );

We have these articles with characteristic records:

ItemIdentifier

Characteristic

Characteristic datatype

Characteristic record value

Item1

animalIngredient

Lookup

Wool

Item2

Ingredient

Text

"Wool"

Item3

animalIngredient

Lookup

Leather

Item4

BakingMaterials

Lookup

Flour

The query above will only return Item1, as Item2 has a different characteristic which uses the datatype String.

Language dependent characteristic records

When not setting a specific language, the search service will search in all languages.

If we want to only search for values in a specific language it is possible to add a language to the CharacteristicExpression as a second parameter.

The optional second parameter is a List containing values of the java datatype Long. The values represent the languages like defined in the Enum.Languages from the repository.

Here is shown how to only get results where the characteristic record has the value "Text" in a specific language.

Characteristic shortDescription = this.modelService.getCharacteristic( "ShortDescription"); //Characteristic with Datatype "Text"
EntityProxy characteristic = animalIngredient.getEntityProxy();
 
List< Long > languagesToSearch = new ArrayList<>();
languagesToSearch.add( ( Long ) englishValueByCode.getKey() );
 
Expression characteristicExp = new CharacteristicExpression( languageDependent, languagesToSearch );
 
Expression valueExp = new ValueExpression( "Text" );
Expression expression = new EqualExpression( characteristicExp, valueExp );

We have these articles with characteristic records:

ItemIdentifier

Characteristic

Language

Characteristic record value

Item1

ShortDescription

English

"Text"

Item2

LongDescription

German

"Text"

The query above will only return Item1, as Item2 has a the same value but for a different language.

Search values regardless of a specific characteristic

It is also possible to search for values contained in a characteristic record without specifing a concrete characteristics.

This example shows how to see all items that have the LookupValue "Milk" somewhere in their characteristic records.

LookupValue milk = IngredientLookup.getValueByKey( "Milk"); //Characteristic with Datatype "Lookup"
 
Expression characteristicExp = new CharacteristicExpression(null);
Expression valueExp = new ValueExpression( milk.getKey() );
Expression expression = new EqualExpression( characteristicExp, valueExp );
 
 
SearchParameters searchParameters = new SearchParameters( DataSource.SUPPLIER, ArticleConst.ENTITY_TYPE,
expression );
EntityProxy[] searchResult = this.searchService.searchAsEntityProxies( new NullProgressMonitor(), searchParameters,
null );

Setting the first parameter of the characteristicExpression to null will result in searching for characteristic records which do have the specified value from the valueExp in any characteristic.

We have these articles with characteristic records:

ItemIdentifier

Characteristic

Characteristic record value

Item1

Ingredient

Salt

Item2

Ingredient

Milk

Item3

Ingredient

Egg

Item4

BakingMaterials

Milk

The query above will return Item2 and Item4 as both records use the same LookupValue.

Descendant Expression

A characteristic expression can be used programmatically in the following way:

Expression descendantExp = new DescendantExpression( parentExpression, childExpression );

Note that there is also a constructor with multiple childExpressions available.

The result will be all entities which have characteristic records matching the parent expression as well as the childexpression in the same hierarchy. The following example will make this clearer.

Example

In this example items are composed of different ingredients from different countries. To model this there is a superordinate characteristic called ingredient and a subordinate characteristic called Country of origin.

We want to find all items containing sugar from Brazil. If we used the characteristic expressions from above and connect them with and, we'd not only find the items with sugar from Brazil but also items that contain sugar from India and meat from Brazil. In order to search for multiple values in a direct hierarchy we can use the descendant expression.

//Superordinate characteristic with data type "Lookup"
Characteristic ingredientCharacteristic = this.modelService.getCharacteristic( "Ingredient" );
EntityProxy ingredient = ingredientCharacteristic.getEntityProxy();
LookupValue sugar = ingredientsLookup.getValueByCode( "SUGAR" );
 
Expression ingredientExp = new CharacteristicExpression( ingredient );
Expression sugarExp = new ValueExpression( sugar.getKey() );
Expression parentExpression = new EqualExpression( ingredientExp, sugarExp );
 
//Subordinate characteristic with data type "Lookup"
Characteristic originCharacteristic = this.modelService.getCharacteristic( "CountryOfOrigin" );
EntityProxy origin = originCharacteristic.getEntityProxy();
LookupValue brazil = originCountriesLookup.getValueByCode( "BRAZIL" );
 
Expression originExp = new CharacteristicExpression( origin );
Expression brazilExp = new ValueExpression( brazil.getKey() );
Expression childExpression = new EqualExpression( originExp, brazilExp );
 
Expression descendantExpression = new DescendantExpression( parentExpression, childExpression );
 
SearchParameters searchParameters = new SearchParameters( DataSource.MASTER, ArticleConst.ENTITY_TYPE,
descendantExpression );
EntityProxy[] searchResult = this.searchService.searchAsEntityProxies( new NullProgressMonitor(), searchParameters,
null );

We have these items with characteristic records:

Item Identifier

Characteristic

Lookup of Characteristic

Characteristic record value

Item1

Ingredient

Ingredients

Sugar

Item1

CountryOfOrigin

OriginCountries

Thailand

Item2

Ingredient

Ingredients

Sugar

Item2

CountryOfOrigin

OriginCountries

India

Item2

Ingredient

Ingredients

Meat

Item2

CountryOfOrigin

OriginCountries

Brazil

Item3

Ingredient

Ingredients

Sugar

Item3

CountryOfOrigin

OriginCountries

Brazil

The query above will return Item3.