2017-04-24 31 views
0

我有兩個蒙戈集合一個蒙戈集合:嗎啡:查詢有@Reference到另一個集合抽出時間

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

而且

public class AccountingTransaction{ 
//Fields here. 
} 

我想查詢「TransactionDetails」使用嗎啡集合框架來獲取引用的「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」和「類型」字段創建:

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

查詢花費了大量的時間,與指標創建。

獲取異常爲「在服務器上找不到光標」。

有沒有什麼改進?我錯過了什麼嗎?

回答

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(); 
+0

鑑於TransactionDetails有幾個數字解讀。的AccountingTransaction(說最大10),我覺得最好是通過使用@Embedded記法嵌入AccountingTransaction,這樣我可以保存網絡調用。 –

相關問題