Actually i have a basex collection with 15000 registries, i'm implementing a jsf and basex aplication, but i got a issue with the performance of the queries, actually i'm using JAXB to convert the xml into objects in java, but is very slow, this is how i do the basex queries:
public class AssetDao implements Dao<Asset>{
public static AssetDao instance;
private String db ="deterioro";
private String assetsModule = "import module namespace assets='http://creativosdigitales.co/cartera/assets' at 'C:/Users/santiago umaña/Google Drive/Deterioro/xquery/assets.xqm';";
private String simulationsModule = "import module namespace simulations='http://creativosdigitales.co/cartera/simulations' at 'C:/Users/santiago umaña/Google Drive/Deterioro/xquery/simulations.xqm';";
public static AssetDao getInstance() {
if(instance == null) {
instance = new AssetDao();
}
return instance;
}
@Override
public List<Asset> get() throws IOException, JAXBException {
List<Asset> results = new ArrayList<Asset>();
try(BaseXClient session = new BaseXClient("localhost", 1984, "admin", "admin")){
session.execute("open "+db);
final String xquery = "for $data in subsequence(//asset, 1, 20) return <asset> {$data/assetid} {$data/payment} {$data/pendingpayments} <balance>{ format-number($data/balance, \"#.00\") }</balance> <npv>{ format-number(sum(//simulation[assetid=$data/assetid]/payment/npv), \"#.00\") }</npv> <difference>{ format-number($data/balance - sum(//simulation[assetid=$data/assetid]/payment/npv), \"#.00\") }</difference> </asset>";
JAXBContext context = JAXBContext.newInstance(Asset.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
Query query = session.query(xquery);
while(query.more()) {
results.add((Asset) unmarshaller.unmarshal(new StringReader(query.next())));
}
return results;
}
}
//custom methods
public List<ExtraField> getExtraFields(String assetId) throws IOException, JAXBException {
List<ExtraField> extraFields = new ArrayList<ExtraField>();
try(BaseXClient session = new BaseXClient("localhost", 1984, "admin", "admin")){
final String xquery = assetsModule
+ "let $db := collection('"+db+"')"
+ "let $asset := assets:asset-info($db, '"+assetId+"')"
+ "return assets:extra-fields($asset)";
JAXBContext context = JAXBContext.newInstance(ExtraField.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
Query query = session.query(xquery);
System.out.println(query.toString());
while(query.more()) {
extraFields.add((ExtraField) unmarshaller.unmarshal(new StringReader(query.next())));
}
return extraFields;
}
}
public List<Simulation> getSimulation(String assetId) throws IOException, JAXBException {
List<Simulation> simulations = new ArrayList<Simulation>();
try(BaseXClient session = new BaseXClient("localhost", 1984, "admin", "admin")){
final String xquery = assetsModule
+ simulationsModule
+ "let $db := collection('"+db+"')"
+ "let $asset := assets:asset-info($db, '"+assetId+"')"
+ "return simulations:simulation-xml($asset)";
JAXBContext context = JAXBContext.newInstance(Simulation.class);
Unmarshaller unmarshaller = context.createUnmarshaller();
Query query = session.query(xquery);
System.out.println(query.toString());
while(query.more()) {
simulations.add((Simulation) unmarshaller.unmarshal(new StringReader(query.next())));
}
return simulations;
}
}
this is my xquery module:
module namespace assets='http://creativosdigitales.co/cartera/assets';
declare function assets:asset-list()
{
for $data in subsequence(//asset, 1, 100)
return
<asset>
{$data/assetid}
{$data/payment}
{$data/pendingpayments}
<balance>{ format-number($data/balance, "#.00") }</balance>
<npv>{ format-number(sum(//simulation[assetid=$data/assetid]/payment/npv), "#.00") }</npv>
<difference>{ format-number($data/balance - sum(//simulation[assetid=$data/assetid]/payment/npv), "#.00") }</difference>
</asset>
};
declare function assets:asset-info($collection, $assetid)
{
<asset>
{ $collection/*/asset[assetid=$assetid]/*,
$collection//simulation[assetid=$assetid],
$collection//punishment[assetid=$assetid] }
</asset>
};
declare function assets:extra-fields($info)
{
let $standard := ('assetid','customerid','customername','amount','term','balance','default','rate','payment','pendingpayments', 'paidpayments', 'extrapayments', 'totalnpv', 'punishment', 'expectednpv', 'simulation', 'policy')
for $x in $info/*[name() != $standard ]
return
<extrafield>
<name>{ $x/name() }</name>
<text>{ $x/text() }</text>
</extrafield>
};
Actually loading 100 items takes some 2 or 3 mins, loading 20 items takes 20 secs, how do I get a better performance to get the items and parse into java objects?
pd: this is my java object:
@ManagedBean
@XmlRootElement(name="asset")
@XmlType(propOrder = {"assetid", "payment", "pendingpayments", "balance", "npv", "difference"})
public class Asset {
private String assetid;
private String payment;
private String pendingpayments;
private String balance;
//net present value
private String npv;
//difference between balance and npv
private String difference;
public Asset() {
// TODO Auto-generated constructor stub
}
@XmlElement(name="assetid")
public String getAssetid() {
return assetid;
}
public void setAssetid(String assetid) {
this.assetid = assetid;
}
@XmlElement(name="payment")
public String getPayment() {
return payment;
}
public void setPayment(String payment) {
this.payment = payment;
}
@XmlElement(name="pendingpayments")
public String getPendingpayments() {
return pendingpayments;
}
public void setPendingpayments(String pendingpayments) {
this.pendingpayments = pendingpayments;
}
@XmlElement(name="balance")
public String getBalance() {
return balance;
}
public void setBalance(String balance) {
this.balance = balance;
}
@XmlElement(name="npv")
public String getNpv() {
return npv;
}
public void setNpv(String npv) {
this.npv = npv;
}
@XmlElement(name="difference")
public String getDifference() {
return difference;
}
public void setDifference(String difference) {
this.difference = difference;
}
}