Morphia:查询一个 mongo collection 对另一个 collection 有 @reference 需要时间
Morphia : Querying a mongo collection having a @reference to another collection taking time
我有两个 mongo collections :
public class TransactionDetails {
private String TYPE="NA";
private Long TransactionDateInLong;
@Reference
List<AccountingTransaction> accountingTransactionList;
}
和
public class AccountingTransaction{
//Fields here.
}
我正在尝试使用吗啡框架查询 "TransactionDetails" collection 以获取引用的 "AccountingTransaction"。
吗啡查询方法如下:
public List<TransactionDetails> getTransactions(Long fromDateInLong, Long endDateInLong) {
Query<TransactionDetails> query = createQuery();
query.and(
query.criteria("TransactionDateInLong").lessThanOrEq(endDateInLong),
query.criteria("TransactionDateInLong").greaterThanOrEq(fromDateInLong)
);
query.and(
query.criteria("TYPE").equal("Income")
);
return query.retrievedFields(true, "accountingTransactionList").asList();
}
为 "TransactionDateInLong" 和 "TYPE" 字段创建索引:
db.getCollection('TransactionDetails').createIndex({"TransactionDateInLong" : 1.0});
db.getCollection('TransactionDetails').createIndex({"TYPE" : "text"});
查询花费了大量时间,创建了索引。
正在获取异常 "Cursor not found on the server"。
有什么改进吗?我错过了什么吗?
如果您引用了很多 AccountingTransaction
这将是一个非常昂贵的查询。 @Reference
只是一个驱动程序功能,所以后台会发生什么:
- 您查询
TransactionDetails
,将其传输到您的应用程序并进行解析。
- 当驱动程序在
@Reference
中找到一个元素时,它将 运行 查询每个元素以获取该元素(每个元素在您的应用程序和 MongoDB).
- 它将在您的应用程序中合并
TransactionDetails
和 AccountingTransaction
。
因此,如果您的查询匹配 100 个 TransactionDetails
,并且每个匹配有 10 个 AccountingTransaction
,您将总共 运行 1 + 100 * 10 个查询。
我认为它在幕后做了完全相同的事情,但我发现这样的查询更具可读性(默认情况下一切都是 and
连接:
return createQuery<TransactionDetails>()
.field("TransactionDateInLong").lessThanOrEq(endDateInLong)
.field("TransactionDateInLong").greaterThanOrEq(fromDateInLong)
.field("TYPE").equal("Income")
.asList();
我有两个 mongo collections :
public class TransactionDetails {
private String TYPE="NA";
private Long TransactionDateInLong;
@Reference
List<AccountingTransaction> accountingTransactionList;
}
和
public class AccountingTransaction{
//Fields here.
}
我正在尝试使用吗啡框架查询 "TransactionDetails" collection 以获取引用的 "AccountingTransaction"。
吗啡查询方法如下:
public List<TransactionDetails> getTransactions(Long fromDateInLong, Long endDateInLong) {
Query<TransactionDetails> query = createQuery();
query.and(
query.criteria("TransactionDateInLong").lessThanOrEq(endDateInLong),
query.criteria("TransactionDateInLong").greaterThanOrEq(fromDateInLong)
);
query.and(
query.criteria("TYPE").equal("Income")
);
return query.retrievedFields(true, "accountingTransactionList").asList();
}
为 "TransactionDateInLong" 和 "TYPE" 字段创建索引:
db.getCollection('TransactionDetails').createIndex({"TransactionDateInLong" : 1.0});
db.getCollection('TransactionDetails').createIndex({"TYPE" : "text"});
查询花费了大量时间,创建了索引。
正在获取异常 "Cursor not found on the server"。
有什么改进吗?我错过了什么吗?
如果您引用了很多 AccountingTransaction
这将是一个非常昂贵的查询。 @Reference
只是一个驱动程序功能,所以后台会发生什么:
- 您查询
TransactionDetails
,将其传输到您的应用程序并进行解析。 - 当驱动程序在
@Reference
中找到一个元素时,它将 运行 查询每个元素以获取该元素(每个元素在您的应用程序和 MongoDB). - 它将在您的应用程序中合并
TransactionDetails
和AccountingTransaction
。
因此,如果您的查询匹配 100 个 TransactionDetails
,并且每个匹配有 10 个 AccountingTransaction
,您将总共 运行 1 + 100 * 10 个查询。
我认为它在幕后做了完全相同的事情,但我发现这样的查询更具可读性(默认情况下一切都是 and
连接:
return createQuery<TransactionDetails>()
.field("TransactionDateInLong").lessThanOrEq(endDateInLong)
.field("TransactionDateInLong").greaterThanOrEq(fromDateInLong)
.field("TYPE").equal("Income")
.asList();