在我们公司,用户已经通过标准前端(Excel)查询activepivot。但是我们想用 Java 构建一个自定义的 MDX 应用程序来查询 ActivePivot。目标是能够订阅多个特定视图并实时检索聚合数据更新,以便为我们的多个内部系统提供数据。
我知道 ActivePivot 实现XMLA 标准并具有自定义 Web 服务。但我想知道发送 MDX 查询的最佳选择是什么,为什么?XMLA 标准是否支持实时更新?
在我们公司,用户已经通过标准前端(Excel)查询activepivot。但是我们想用 Java 构建一个自定义的 MDX 应用程序来查询 ActivePivot。目标是能够订阅多个特定视图并实时检索聚合数据更新,以便为我们的多个内部系统提供数据。
我知道 ActivePivot 实现XMLA 标准并具有自定义 Web 服务。但我想知道发送 MDX 查询的最佳选择是什么,为什么?XMLA 标准是否支持实时更新?
ActivePivot 确实主要使用 MDX 语言进行查询。正如您所指出的,有几种不同的方法可以将 MDX 查询发送到 ActivePivot 并获得答案。
第一种也是最标准的方法是使用 XMLA 标准查询 ActivePivot。例如,当您使用 Excel、Tableau 或大多数支持 MDX 的 GUI 查询 ActivePivot 时,就会发生这种情况。但是,此方法仅对 ad-hoc 查询有效。您不能将 ActivePivot 的连续查询功能与 XMLA 一起使用。
为了注册连续查询,您需要使用 ActivePivot 附带的现有 Web 服务,特别是:
一般工作流程如下:
此时,侦听器线程将接收已注册 MDX 查询的当前结果集,然后将仅接收更改的单元格,因为它们的值会随着新事务的变化而变化。
这是查询注册的示例代码:
// Create my MDX query
final String mdx =
"SELECT NON EMPTY {DrilldownLevel({[Bookings].[ALL].[AllMember]})} ON ROWS " +
"FROM [EquityDerivativesCube] " +
"WHERE ([Measures].[contributors.COUNT])";
final IMDXQuery mdxQuery = new MDXQuery(mdx);
// Retrieve your various webservices
final IStreamingService streamingService = ...;
final ILongPollingService longPollingService = ...;
final IIdGenerator idGenerator = ...;
// Initiate a (long polling based) communication channel
final String listenerId = idGenerator.generateListenerIds(1)[0];
longPollingService.addListener(PUBLICATION_DOMAIN, listenerId);
new Thread(new Listener(longPollingService, listenerId)).start();
// Subscribe a continuous mdx query, events will be received
// through the communication channel.
final String mdxStreamId = idGenerator.generateListenerIds(1)[0];
final IStreamProperties mdxStreamProperties = new StreamProperties(
mdxStreamId,
PUBLICATION_DOMAIN,
InitialState.STARTED,
true);
streamingService.createStream(mdxQuery, mdxStreamProperties);
// From now on the listener will receive the real-time events
这是一个简单的监听器代码:
public class Listener implements Runnable {
final ILongPollingService service;
final String listenerId;
Listener(ILongPollingService service, String listenerId) {
this.service = service;
this.listenerId = listenerId;
}
@Override
public void run() {
for(int iteration = 0; iteration < 100; iteration++) {
IBulkedStreamEvents events = service.listen(listenerId);
if(events != null) {
logger.log(Level.INFO, "Received events:");
for(final IDomainStreamEvent domainEvent: events.getDomainEvents()) {
for(final IStreamEvent event : domainEvent.getEvents())
logger.log(Level.INFO, event.toString());
}
} else {
logger.log(Level.INFO, "No events received.");
}
}
}
}