Discover the platform
Several common concepts and conventions apply throughout the Optimizely Community (formerly Social) API. An understanding of these strategies is helpful in discovering the tools available to you.
Services
The primary point of interaction with the Optimizely Community API is the service classes exposed by each platform's features. Each service implements an interface which conforms to the following naming convention: I{Feature-Name}Service
. Examples include:
ICommentService
IRatingService
IGroupService
Suppose a platform feature is installed on an Optimizely Content Management System (CMS) site with the feature's site integration package. In that case, you can get an instance of a service from the inversion of control (IoC) container.
Example
var commentService = EPiServer.ServiceLocation.ServiceLocator.Current.GetInstance<ICommentService>();
If a platform feature is installed on a non-Optimizely CMS site, you can get an instance of a service from the default factory classes provided within the package.
Example
var factory = new EPiServer.Social.Moderation.Factories.DefaultWorkflowServiceFactory();
var workflowService = factory.Create();
Data models
You can find the data models consumed and returned by the Community API's services beneath the "core" namespace accompanying a particular platform feature. The convention for "core" namespaces is EPiServer.Social.{Feature-Name}.Core
. For example:
EPiServer.Social.Comments.Core
EPiServer.Social.Ratings.Core
Exceptions
You can find exceptions thrown by the Community API's services beneath the Core
namespace accompanying a particular platform feature. The convention for Core
namespaces is: EPiServer.Social.{Feature-Name}.Core
. For example:
EPiServer.Social.Comments.Core
EPiServer.Social.Ratings.Core
Additionally, you may find exception types, which are shared throughout the platform, in the EPiServer.Social.Common
 namespace.
Platform exceptions
The features of the Optimizely Community API share several exception types to communicate general platform error situations.
SocialAuthenticationException
A SocialAuthenticationException
is thrown by Optimizely Community API service methods when a request is deemed unauthentic.
This error most commonly occurs when:
- The application's configuration is missing one or more of its authentication settings.
- The application's configuration contains inaccurate authentication settings.
- The application's server time is inaccurate.
For information regarding configuration and authentication, see Get connected in Install Optimizely Community.
MaximumDataSizeExceededException
A MaximumDataSizeExceededException
is thrown by methods of an Optimizely Community API service when a request exceeds the platform's size restrictions.
The platform accepts social content up to 10 kilobytes in size. This restriction applies to any given social entity, including the native properties of the platform's content models, optional extension data, and any overhead of those models.
For example, consider a simple comment containing an author, body, and parent reference. Consider that you also composed this comment with custom extension data. The content associated with each of those native comment properties and the extension data contribute to the total size of the request.
The platform does not explicitly restrict the amount of content associated with any individual property of a social content model. This lets you prioritize the content size that the application allows to native content models versus custom extension data.
Note
The application should enforce limits on the amount of content that may be contributed, as applicable to its use cases. In doing so, it minimizes the likelihood that this exception may occur.
RateLimitExceededException
A RateLimitExceededException
is thrown by all methods of an Optimizely Community API service when an application issues too many requests over a short period of time. All requests issued to Optimizely Community are tallied and compared against the rate limit. When an application exceeds the rate limit, Optimizely Community API stops processing requests until a certain time has elapsed (a "request interval").
The exception provides additional information to help the application regulate its request rate. That information includes:
RequestInterval
– The length of time in which requests are tallied.RequestsIssued
– The number of requests already issued in the request interval.RequestLimit
– The maximum number of requests allowed in a given request interval.RetryAfter
– The time remaining until the application may resume issuing requests.
If your application regularly encounters this exception, consider:
- Optimizing your code to minimize unnecessary API calls
- Caching data that is frequently accessed
- Actively regulating the application's request rate to ensure that the application never encounters the issue
- Implementing logic to pause and retry requests after reaching the limit
SocialCommunicationException
An SocialCommunicationException
is thrown by Optimizely Community API service methods when a request encounters a fundamental communication issue.
This error most commonly occurs when:
- The application cannot connect or communicate with Optimizely Community API cloud services.
- A request from the application exceeds the configured timeout.
SocialException
A SocialException
is thrown by Optimizely Community API service methods when a request encounters an unexpected error scenario. The exception contains a message, status code, error code, and additional reasoning to describe the error further.
This error most commonly occurs when:
- The application's configuration is missing or malformed.
- The platform encountered an unexpected service error.
Feature exceptions
The individual services of the Optimizely Community API may also throw exceptions unique to the feature they support. Information on feature-specific exceptions can be found in the documentation for each API.
Reference and IDs
The Optimizely Community API has two means of identifying data: by reference and by ID. The structure and function of these classifiers are similar, but there are important semantic distinctions between them. See also:Â Work with Optimizely Community API References.
Ids
The Id
classes that appear in each Community API feature pertain specifically to that feature's entities. Their values are internally-generated and used to distinguish individual entities within the system.
Id
classes conform to the following naming convention: {Feature-Name}Id. Examples include:
CommentId
GroupId
WorkflowId
Id
classes are accepted by the platform's services when retrieving specific data instances.
Reference
The Reference
class that appears in the Optimizely Community API refers to users or resources outside the platform. References identify entities in other systems. Use a reference value to establish relationships between social content and resources or users to which that content applies.
The developer defines the value contained within a reference class. It contains the information necessary to identify or classify the resource or user to which social content is related.
The platform provides a Reference
class that is used to identify any target entity in your application. For example, a resource, like Optimizely CMS content, or a product or a user, like an Optimizely CMS user.
Best practices for defining references
As a developer, you are free to define references as it suits your application. Ultimately, you want to ensure that your reference scheme is:
- Capable of uniquely identifying your application's entities
- Capable of being interpreted by your application
- Robust enough to support your application's inevitable enhancements and changes
You are accustomed to considering identifiers unique IDs, such as GUIDs or hashes. These are often sufficient to identify data within a single system but may be insufficient when integrating multiple systems. When designing your scheme for defining reference values, consider the following factors:
- Platform – In what platform does your resource or user reside?
- Provider – Does that platform deliver resources or users through different providers?
- Classification – What type of data is being referenced? Is it content, a product, a CMS user, or an ecommerce customer?
- Categorization – Is there a taxonomical nature to a resource or a user's identification?
- Facets – Do you intend to refer to a facet of some resource, like a product's price or color?
These considerations play a role in designing a meaningful reference scheme.
A URI or similar namespace scheme provides an ideal template for a reference. Consider the following example of a reference scheme that might be applied to ecommerce content:
resource://optimizely/commerce/{product-identifier}/{variant-identifier}/{facet-identifier}
This example accounts for the content's classification, platform, hierarchical identifiers, and facets.
Criteria
The Optimizely Community API's services let you retrieve custom result sets of the content which you are managing with it. These services accept criteria that dictate how to retrieve a result set. A class named Criteria<TFilter>
encapsulates the specifications necessary to retrieve a collection of results from one of the platform services.
Filter
The type parameter TFilter
 identifies the class that encapsulates the filter specifications applicable to the service and the content it manages. The particular filter class required by a service is identified in the signature of its retrieval methods.
The Filter
property accepts an instance of the filter class, which captures the specifications you want to refine a result set.
PageInfo
The PageInfo
property accepts an instance of a class by the same name, which defines the specifications by which a result set is paginated into collections of a fixed number of results.
The PageInfo
class captures a page size, representing the maximum number of results to retrieve. The page size must be greater than or equal to zero. If the page size is not specified, a default of 10 items is applied.
PageInfo
also captures a page offset, representing the index (zero-based) from which to begin retrieving results. The page offset must be greater than or equal to zero.
PageInfo
also lets the user specify if they want to calculate a total result count for the query. This count is returned with the TotalCount
 property on the ResultPage
. By default, no total count is calculated.
Best practices for paginating results
When optimizing your implementation, your page size, page offsets, and total count are important. Large page sizes or deep offsets can negatively impact the performance of your content retrieval. Consider your request size, volume, and user experience to find the appropriate balance when determining your application's pagination strategy. Additionally, retrieving the TotalCount
for a query when it is not needed adversely affects the time it takes to return a ResultPage
.
OrderBy
The OrderBy
 property accepts a collection of rules describing how to sort the result set. An instance of a class named represents each sorting ruleSortInfo
.
An instance of the SortInfo
class identifies the field on which to sort and the direction in which to sort. For example, you might sort a result set of comments by the field representing their publication date in descending order.
A subset of the fields on the platform's data models is available for sorting. This curated set of fields is exposed through classes that adhere to a particular convention. These fields are statically exposed on classes named {Feature-Name}SortFields
. For example, CommentSortFields
and RatingSortFields
.
The sorting rules identified in the collection are processed in order by the service, which executes the result retrieval. Each subsequent rule in the collection represents a fallback if multiple results share a matching value in the field identified by the preceding sorting rule. For example, suppose you sort ratings by their value. In that case, you might specify a fallback of the ratings' modification date to ensure that the platform consistently orders ratings with the same value.
Best practices for sorting results
The platform cannot guarantee the order of results, from request to request, if a field targeted for sorting contains matching values for multiple result items. If consistency in result ordering is relevant, specifying one or more fallback sorting rules is important. Consistency is particularly important if your application lets users navigate through multiple pages of result items.
The sorting of string values will occur based on the Unicode value of a character. If your application requires alternative ordering for a property, you should standardize the data in code and store it as a duplicate property on the extension data.
Result sets
The services of the Optimizely Community API, which expose bulk retrieval capabilities, deliver their results in a paginated fashion. A page of results is represented with a class named ResultPage<T>
.
Results
The type parameter T
identifies the class representing the model for the data to be returned. For example, Comment
or Rating
. The Results
property gets the collection of individual result items that comprise the page.
TotalCount
The TotalCount
property provides a total count of items resulting from the query. For example, a product has 20 comments. In requesting this product's comments, a page size of 10 is specified. The resulting page of comments would include 10 items, while its TotalCount
property would have a value of 20. A total count is calculated when the CalculateTotalCount
property of the PageInfo
associated with your criteria is assigned a value of true. If CalculateTotalCount
is set to false, the total count is -1.
Info
The Info
property refers to the paging specifications, which were specified when the request that produced the page was issued.
HasMore
The HasMore
property provides a boolean that denotes whether the query has found more items beyond the page returned. An example of this would be a query with 11 results in the database, and a query is issued with a PageSize
of 10. The ResultPage
would return 10 results and have a HasMore value of true. This provides a developer insight into whether an additional query with a PageOffset
of 10 would return any items in the ResultPage
. In this example, if a second query were issued, it would return 1 item in the ResultPage and have a HasMore
value of false.
Composites
Every application has unique needs concerning the structure of its social content. Applications have different systems to integrate with, different visions of what community-generated content is comprised of, and different entities and actions to moderate. An application needs the freedom to store, relate, and present social content in a form that it determines appropriate. With this in mind, the features of the Optimizely Community API distill social concepts to their essence and invite data extensibility by allowing its native entities to be composed with custom data models.
- What is a composite?
- Defining extension data
- Composite criteria
- Filtering composites
- Sorting composites
What is a composite?
The Optimizely Community API encourages data extensibility by compiling native platform entities with custom extension data. Extension data is a .NET class, defined within your application, intended to capture additional details necessary to shape a platform entity to meet your application's needs.
The platform's services encapsulate the relationship between their entities and extension data with the Composite
 class. The Composite
class represents a simple pairing, an instance of a native platform entity, and its associated extension data.
Define extension data
Extension data is a .NET class, defined within your application, and intended to capture additional details necessary to shape a platform entity to meet your application's needs. As you design the classes that represent your extension data, consider the following:
- Queryability – The platform can sort and filter composite result sets according to a select set of primitive value types within your extension data. If you intend to filter or sort by particular extension data values, it is important to design your extension data class accordingly. (See Filtering Composites.)
- Maintainability – Anticipate the likelihood of future enhancements to your application's data and the impact of changes on your classes or business logic. Think of your extension data as a schema and approach its design carefully.
- Performance – Keep extension data light to minimize the likelihood of performance penalties in its transfer.
Extension data is subject to the realities and limitations of today's serialization engines. To ensure that your data can be stored and retrieved, the extension data class must abide by the following constraints:
- It must have a public, parameter-less constructor.
- It must not refer to nested data in a polymorphic manner. For example, the class must not refer to a child as the Object type.
- It must not contain self-references or referential loops.
- The class name and the assemblies' names and namespaces containing it must remain stable to ensure that the platform can identify the stored data.
- An instance of this data contributes to the total size of a request to the platform. Minimize the size of this data to avoid exceeding platform size restrictions.
If these constraints are not respected, you may encounter errors while storing and retrieving composites.
You should use only classes defined within your application when defining extension data. The data models of this platform are not guaranteed to be serializable. Defining your own classes, rather than utilizing those of a third-party library, also helps to future-proof your schema. This mitigates the risk of volatility within your dependencies.
When defining extension data, consider these additional caveats:
- DateTime values in extension data are stored and returned as Universal Time Coordinated (UTC).
- DateTime precision is consistent up to the millisecond value.
- There is no support for the Decimal type in the Optimizely Community API Platform. As a result, a Decimal value is stored as a double and can be subject to a rounding error.
Composite criteria
The Optimizely Community API lets you retrieve result sets of composite data like its standard entities. Each platform service that supports Composites provides methods for retrieving them. The services delivering result sets of composite data accept composite criteria. These criteria are represented by a class named CompositeCriteria\<TFilter, TExtension>
.
The CompositeCriteria
class extends the standard Criteria
class, incorporating its capabilities. The filters and other specifications exposed by Criteria
may be applied in conjunction with the additional enhancements afforded by the CompositeCriteria
class.
ExtensionFilter
The TExtension
type parameter identifies the type of extension data to be retrieved. This serves as an implicit filter; only Composites
with extension data of this type are retrieved.
The ExtensionFilter
property accepts a Boolean expression capable of filtering your result set by values in your extension data. This expression is represented as a tree structure and may combine multiple Boolean expressions with logical operators (like "AND"), also provided by the platform. For information regarding the construction of these expressions, see Filtering Composites.
IncludeSubclasses
The IncludeSubclasses
property accepts a value, which indicates if the result set should include items bearing extension data that implement a subclass of the type identified by the TExtension type parameter.
- True indicates that the result set may include composites where
TExtension
appears anywhere within the type hierarchy of their associated extension data. This is the default behavior. - False indicates that the result set includes only composites where their extension data is explicit of the
TExtension
type.
Filter composites
Composites lets you extend the platform by composing platform entities with supplemental data of their own design. This feature is enhanced by the ability to define custom filters for result sets, which include that data. This type of refinement is a Filter Expression.
Filter Expressions are Boolean expressions, represented as tree structures, which can filter a result set of Composites by values included within their extension data. Consider an example where an application composes a comment with extension data via the following definition:
public class MyCommentExtension {
public int LuckyNumber {
get;
set;
}
public string FavoriteTeam {
get;
set;
}
public DateTime Birthday {
get;
set;
}
}
In this example, your application requires you to filter composite comments to those with a LuckyNumber of 7 and a Birthday before 1990. A filter that accounts for these specifications can be represented as the following expression tree:
The platform provides the tools necessary to construct such an expression tree. The primary point of access for doing so is a class named FilterExpressionBuilder<TExtension>
.
The FilterExpressionBuilder
exposes convenient methods and operator overloads for individual Boolean and logical operators available to developers when defining Filter Expressions. This class's TExtension
type parameter identifies the type of extension data that the resulting expression is intended to target.
The operators available for defining filters include:
Builder method | Class | Description | Builder Operator Overloads |
---|---|---|---|
Field | FieldExpression | Represents a field. | Â |
EqualTo | EqualToExpression | Represents an equality comparison. | == |
Contains | ContainsExpression | Represents an equality comparison in collections | Â |
Any | AnyExpression | Represents the inclusion of a field value in a given collection | Â |
GreaterThan | GreaterThanExpression | Represents a greater than comparison | > |
GreaterThanOrEqualTo | GreaterThanOrEqualToExpression | Represents a greater than or equal to comparison | > = |
LessThan | LessThanExpression | Represents a less than comparison | < |
LessThanOrEqualTo | LessThanOrEqualToExpression | Represents a less than or equal to comparison | <= |
And | AndExpression | Represents a logical AND of a collection of filter expressions. | & |
Or | OrExpression | Represents a logical OR of a collection of filter expressions. |
The expressions representing Boolean operators, which are available within the platform, can compare fields of the following .NET data types:
- String
- Boolean
- Int
- Long
- Double
- DateTime
Continuing the above example, consider how a developer would leverage the FilterExpressionBuilder
to construct the necessary Filter Expression.
var luckyNumberOf7 = FilterExpressionBuilder<MyCommentExtension>.Field(d => d.LuckyNumber).EqualTo(7);
The snippet above constructs a Boolean expression, which evaluates the LuckyNumber field of our extension data for a value of 7. This example features two method calls:
- The
Field
method accepts a lambda expression, which selects the extension data field we intend to represent in the Filter Expression. - The
FieldExpression
'sEqualTo
method accepts a value, constructing anEqualToExpression
where ourFieldExpression
represents its left operand and the value represents its right operand.
The result of this operation is the expression tree below:
var bornBefore1990 = FilterExpressionBuilder<MyCommentExtension>.Field(d => d.Birthday).LessThan(new DateTime(1990, 1, 1));
Similarly, the snippet above constructs a Boolean expression that evaluates the Birthday field of your extension data for a value before the year 1990. The result of this operation is the expression tree below:
You can combine these two Boolean expressions into a single Filter Expression by logically ANDing them, as demonstrated in the snippet below:
var combinedExpression = FilterExpressionBuilder<MyCommentExtension>.And(luckyNumberOf7, bornBefore1990);
The result of this operation, which completes your filter for this example, is the expression tree below:
To put these snippets in context, the construction of criteria reflecting a request for composite comments might appear as follows:
var luckyNumberOf7 = FilterExpressionBuilder<MyCommentExtension>.Field(d => d.LuckyNumber).EqualTo(7);
var bornBefore1990 = FilterExpressionBuilder<MyCommentExtension>.Field(d => d.Birthday).LessThan(new DateTime(1990, 1, 1));
var combinedExpression = FilterExpressionBuilder<MyCommentExtension>.And(luckyNumberOf7, bornBefore1990);
var criteria = new CompositeCriteria<Comment, MyCommentExtension>
{
ExtensionFilter = combinedExpression
};
Best practices for defining filter expressions
- Elaborate filter expressions can impact the performance of your requests. For optimal performance, minimize the complexity and depth of your expressions.
- Changes to the structure of your extension data classes may result in malformed expressions.
- Malformed expressions may result in unexpected results or empty result sets. Think of your extension data as a schema and carefully approach its design.
Filter expressions
The examples for each filter expression below assume the following comment extension:
public class MyCommentExtension {
public int LuckyNumber {
get;
set;
}
public List<string> FavoriteTeams {
get;
set;
}
public DateTime Birthday {
get;
set;
}
}
Any expression
Use the Any
expression to filter both single-value and multi-value extension fields by a list of values. As an example of using the Any
expression with a single-value extension field, assume that we want to read all comments for which the single-value LuckyNumber
extension field matches any of three drawn lucky numbers. The following code shows how this is done with the Any expression:
var drawnLuckyNumbers = new List<long>{3, 7, 9};
var commentsWithDrawnLuckyNumbers = FilterExpressionBuilder<MyCommentExtension>.Field(ext => ext.LuckyNumber).Any(drawnLuckyNumbers);
var criteria = new CompositeCriteria<Comment, MyCommentExtension>
{
ExtensionFilter = commentsWithDrawnLuckyNumbers
};
As an example of using the Any expression with a multi-value extension field, assume that we want to read all comments for which the multi-value favoriteTeams
extension field contains either "New England Patriots" or "Boston Red Sox". The following code shows how this is done with the Any
expression.
var mostFavoriteTeams = new List<string>{"New England Patriots", "Boston Red Sox"};
var commentsWithMostFavoriteTeams = FilterExpressionBuilder<MyCommentExtension>.Field(ext => ext.FavoriteTeams).Any(mostFavoriteTeams);
var criteria = new CompositeCriteria<Comment, MyCommentExtension>
{
ExtensionFilter = commentsWithMostFavoriteTeams
};
Contains expression
The Contains
expression can be used to filter both single-value and multi-value extension fields by a single value. As an example of using the Contains
expression with a single-value extension field, assume that we want to read all comments for which the single-value LuckyNumber
extension field matches drawn lucky number 7. The following code shows how this is done with the Contains
expression:
var luckyNumber = 7;
var commentsWithLuckNumber = FilterExpressionBuilder<MyCommentExtension>.Field(ext => ext.LuckyNumber).Contains(luckyNumber);
var criteria = new CompositeCriteria<Comment, MyCommentExtension>
{
ExtensionFilter = commentsWithLuckNumber
};
As an example of using the Contains
expression with a multi-value extension field, assume that you want to read all comments for which the multi-value favoriteTeams
extension field contains "Boston Celtics". The following code shows how this is done with the Contains
expression.
var favoriteTeam = "Boston Celtics";
var commentsWithFavoriteTeam = FilterExpressionBuilder<MyCommentExtension>.Field(ext => ext.FavoriteTeams).Contains(favoriteTeam);
var criteria = new CompositeCriteria<Comment, MyCommentExtension>
{
ExtensionFilter = commentsWithFavoriteTeam
};
EqualTo expression
The EqualTo
expression is used to filter documents by an extension field whose value equals a given value. The EqualTo
expression in the following example will match any comments with a Birthday on new year 2000.
var newYear2000 = new DateTime(2000, 1, 1);
var commentsWithMatchingBirthday = FilterExpressionBuilder<MyCommentExtension>.Field(d => d.Birthday).EqualTo(newYear2000);
var criteria = new CompositeCriteria<Comment, MyCommentExtension>
{
ExtensionFilter = commentsWithMatchingBirthday
};
LessThanOrEqualTo expression
The LessThanOrEqualTo
expression filters documents by an extension field whose value is less than or equal to a given value. The LessThanOrEqualTo
expression in the following example will match any comments with a Birthday on or before new year 2000.
var newYear2000 = new DateTime(2000, 1, 1);
var commentsWithMatchingBirthday = FilterExpressionBuilder<MyCommentExtension>.Field(d => d.Birthday).LessThanOrEqualTo(newYear2000);
var criteria = new CompositeCriteria<Comment, MyCommentExtension>
{
ExtensionFilter = commentsWithMatchingBirthday
};
GreaterThanOrEqualTo expression
The GreaterThanOrEqualTo
expression filters documents by an extension field whose value is greater than or equal to a given value. The GreaterThanOrEqualTo
expression in the following example will match any comments with a Birthday on or after new year 2000.
var newYear2000 = new DateTime(2000, 1, 1);
var commentsWithMatchingBirthday = FilterExpressionBuilder<MyCommentExtension>.Field(d => d.Birthday).GreaterThanOrEqualTo(newYear2000);
var criteria = new CompositeCriteria<Comment, MyCommentExtension>
{
ExtensionFilter = commentsWithMatchingBirthday
};
LessThan expression
The LessThan
expression filters documents by an extension field whose value is less than a given value. The LessThan
expression in the following example matches any comments with a Birthday before 2000.
var newYear2000 = new DateTime(2000, 1, 1);
var commentsWithMatchingBirthday = FilterExpressionBuilder<MyCommentExtension>.Field(d => d.Birthday).LessThan(newYear2000);
var criteria = new CompositeCriteria<Comment, MyCommentExtension>
{
ExtensionFilter = commentsWithMatchingBirthday
};
GreaterThan expression
The GreaterThan
expression filters documents by an extension field whose value exceeds a given value. The GreaterThan
expression in the following example will match any comments with a Birthday after new year 2000.
var newYear2000 = new DateTime(2000, 1, 1);
var commentsWithMatchingBirthday = FilterExpressionBuilder<MyCommentExtension>.Field(d => d.Birthday).GreaterThan(newYear2000);
var criteria = new CompositeCriteria<Comment, MyCommentExtension>
{
ExtensionFilter = commentsWithMatchingBirthday
};
And expression
The And
expression filters documents by one or more sub-expressions where a document is matched by all the sub-expressions. The And
expression in the following example will match any comments with a Birthday in the year 2000.
var startYear2000 = new DateTime(2000, 1, 1);
var endYear2000 = new DateTime(2000, 12, 31);
var commentsMatchingBirthday1 = FilterExpressionBuilder<MyCommentExtension>.Field(d => d.Birthday).GreaterThanOrEqualTo(startYear2000);
var commentsMatchingBirthday2 = FilterExpressionBuilder<MyCommentExtension>.Field(d => d.Birthday).LessThanOrEqualTo(endYear2000);
var commentsWithBirthdayInYear2000 = FilterExpressionBuilder<MyCommentExtension>.Field(d => d.Birthday).And(commentsMatchingBirthday1, commentsMatchingBirthday2);
var criteria = new CompositeCriteria<Comment, MyCommentExtension>
{
ExtensionFilter = commentsWithBirthdayInYear2000
};
Or expression
The Or
expression is used to filter documents by one or more sub-expressions where any of the sub-expressions matches a document. The Or
expression in the following example will match any comments with a Birthday in year 2000 Or LuckyNumber 7.
var startYear2000 = new DateTime(2000, 1, 1);
var endYear2000 = new DateTime(2000, 12, 31);
var commentsMatchingBirthday1 = FilterExpressionBuilder<MyCommentExtension>.Field(d => d.Birthday).GreaterThanOrEqualTo(startYear2000);
var commentsMatchingBirthday2 = FilterExpressionBuilder<MyCommentExtension>.Field(d => d.Birthday).LessThanOrEqualTo(endYear2000);
var commentsWithBirthdayInYear2000 = FilterExpressionBuilder<MyCommentExtension>.Field(d => d.Birthday).And(commentsMatchingBirthday1, commentsMatchingBirthday2);
var luckyNumber = 7;
var commentsWithLuckyNumber = FilterExpressionBuilder<MyCommentExtension>.Field(ext => ext.LuckyNumber).Contains(luckyNumber);
var theWinner = FilterExpressionBuilder<MyCommentExtension>.Field(d => d.Birthday).Or(commentsWithBirthdayInYear2000, commentsWithLuckyNumber);
var criteria = new CompositeCriteria<Comment, MyCommentExtension>
{
ExtensionFilter = theWinner
};
Sort composites
Just as fields represented within extension data may be referenced in filtering Composite
result sets, they may also be applied in sorting result sets. Sorting rules are defined with the CompositeCriteria
class, just as they are for the standard Criteria
class. Its OrderBy
property accepts a collection of rules describing how to sort the result set. An instance of a class named represents each sorting ruleSortInfo
.
An instance of the SortInfo
class identifies the field and the direction on which to sort. A field represented in your extension data may be identified in the construction of SortInfo
by leveraging the FilterExpressionBuilder
. See Filtering Composites.
Consider an example where an application composes a comment with extension data with the following definition:
public class MyCommentExtension {
public int LuckyNumber {
get;
set;
}
public string FavoriteTeam {
get;
set;
}
public DateTime Birthday {
get;
set;
}
}
The snippet below demonstrates the construction of an instance of SortInfo
, targeting the LuckyNumber field of such an extension:
var sortField = new SortField(FilterExpressionBuilder<MyCommentExtension>.Field(d => d.LuckyNumber));
var sortingRule = new SortInfo(sortField, true);
var criteria = new CompositeCriteria<Comment, MyCommentExtension>
{
OrderBy = new List<SortInfo> { sortingRule }
};
In this example, an instance of SortField
is constructed. It accepts a FieldExpression
representing the LuckyNumber field of your extension data. Next, an instance of SortInfo is constructed to refer to this SortField
, and assigned to the criteria as a sorting rule.
Sorting rules targeting the fields represented within extension data may be applied to your criteria in conjunction with those targeting the curated set of sort fields available for platform entities. See Criteria.
Asynchronous methods
In addition to synchronous methods, the Optimizely Community API services expose method overloads for use in an asynchronous programming model. Suppose the needs of your application are such that you cannot block an application thread while invoking the Optimizely Community API services. In that case, you can employ a corresponding overload of that method.
In a synchronous operation, the calling thread cannot continue until the API completes its operation. On the other hand, when these overloads are invoked using the appropriate asynchronous .NET techniques, it can now run to completion without blocking. Meanwhile, the calling thread in your application can perform its additional business logic in parallel. Being able to perform tasks in parallel can improve the overall responsiveness and performance of your application.
All asynchronous methods in the Optimizely Community API framework end with the Async suffix and return a .NET Task object. A Task object is used to represent an asynchronous operation. For more details, refer to Microsoft's documentation for Task-based Asynchronous Programming. An Async overload is available for any Optimizely Community API method that can block the calling thread while communicating with the framework's cloud services to operate.
You can use C#'s async and await keywords to perform long-running work without blocking the calling thread. For more details, see Microsoft's documentation on Asynchronous Programming with async and await.
Optimizely Community API asynchronous overloads are discussed in detail with code examples alongside their synchronous versions in the Optimizely Community API feature documentation.
Updated 6 months ago