Morphia:查询具有@reference的mongo集合到另一个集合需要花费时间

时间:2017-04-24 09:58:54

标签: mongodb morphia

我有两个mongo集合:

public class TransactionDetails {
    private String TYPE="NA";
    private Long TransactionDateInLong;
    @Reference
    List<AccountingTransaction> accountingTransactionList;
}

public class AccountingTransaction{
//Fields here.
}

我正在尝试查询&#34; TransactionDetails&#34;使用morphia框架收集引用的&#34; AccountingTransaction&#34;。

以下是morphia查询的方法:

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();
    }

为&#34; TransactionDateInLong&#34;创建了索引。和&#34; TYPE&#34;领域:

db.getCollection('TransactionDetails').createIndex({"TransactionDateInLong" : 1.0});
db.getCollection('TransactionDetails').createIndex({"TYPE" : "text"});

查询花费了大量时间,并创建了索引。

将异常作为&#34;在服务器上找不到光标&#34;。

有任何改进吗?我错过了什么吗?

1 个答案:

答案 0 :(得分:0)

如果你引用了很多AccountingTransaction,这将是一个非常昂贵的查询。 @Reference只是一个驱动程序功能,因此后台会发生什么:

  • 您查询TransactionDetails,将其传输到您的应用程序并解析它。
  • 当驱动程序在@Reference中找到一个元素时,它将为每个元素运行一个查询以获取该元素(每个元素在您的应用程序和MongoDB之间进行另一次往返)。
  • 它会在您的应用中合并TransactionDetailsAccountingTransaction

因此,如果您的查询与100 TransactionDetails匹配,并且每个查询都有10 AccountingTransaction,那么您将总共运行1 + 100 * 10个查询。

我认为它在幕后完全相同,但我发现这样的查询更具可读性(默认情况下,所有内容都是and连接:

return createQuery<TransactionDetails>()
    .field("TransactionDateInLong").lessThanOrEq(endDateInLong)
    .field("TransactionDateInLong").greaterThanOrEq(fromDateInLong)
    .field("TYPE").equal("Income")
    .asList();