2014-06-15 66 views
-1

我有以下測試:爲什麼Sum()在我的索引中不起作用?

public class ListingEventTest 
{ 
    public ListingEventTest() 
    { 
     Artists = new List<ArtistTest>(); 
    } 
    public List<ArtistTest> Artists { get; set; } 
    public string Id { get; set; } 
    public string Name { get; set; } 
    public double Popularity { get; set; } 
} 

public class ArtistTest 
{ 
    public string Id { get; set; } 
    public Stat Stats { get; set; } 
} 

public class Stat 
{ 
    public double Popularity { get; set; } 
} 


public class ArtistsWithStats_ByName : AbstractIndexCreationTask<ListingEventTest> 
{ 
    public ArtistsWithStats_ByName() 
    { 
     Map = listingEvents => from listingEvent in listingEvents 
           let artists = LoadDocument<ArtistTest>(listingEvent.Artists.Select(x => x.Id)) 
           select new 
           { 
            Popularity = artists.Average(x => x.Stats.Popularity), 
            listingEvent.Name 
           }; 
    } 
} 



[TestFixture] 
public class IndexCanDoSums 
{ 
    [Test] 
    public async void WhenListingEventArtistsHaveStatsIndexReturnsPopularity() 
    { 
     var store = new EmbeddableDocumentStore 
     { 
      UseEmbeddedHttpServer = true, 
      Configuration = 
      { 
       RunInUnreliableYetFastModeThatIsNotSuitableForProduction = true, 
       RunInMemory = true, 

      } 
     }.Initialize(); 

     IndexCreation.CreateIndexes(typeof(ArtistsWithStats_ByName).Assembly, store); 

     using (var session = store.OpenAsyncSession()) 
     { 
      for (int i = 0; i < 10; i++) 
      { 
       var le = new ListingEventTest 
       { 
        Name = "test-" + i 
       }; 

       await session.StoreAsync(le); 

       for (int j = 0; j < 2; j++) 
       { 
        var artist = new ArtistTest 
        { 
         Stats = new Stat 
         { 
          Popularity = 0.89d 
         } 
        }; 

        await session.StoreAsync(artist); 

        le.Artists.Add(artist); 
       } 

       await session.SaveChangesAsync(); 
      } 
     } 

     Thread.Sleep(2000); 

     using (var session = store.OpenAsyncSession()) 
     { 
      var query = session 
      .Advanced.AsyncLuceneQuery<ListingEventTest>("ArtistsWithStats/ByName"); 

      var result = await query.ToListAsync(); 

      result.First().Popularity.Should().NotBe(0); 
     } 
    } 
} 

當我詢問該指數Popularity始終爲0

任何想法?

+1

給出一個小而完整的例子,說明我們實際上可以嘗試的問題。 –

+0

但是這應該是正確的? – iwayneo

+1

不錯,你輸入的代碼甚至不會編譯,因爲'.Name'後面沒有逗號。說它應該*或*不應該*做什麼是一個道德問題;你聲稱它*做*做一件特別的事情;證明理由是對理解它的第一步。這可能是因爲你犯了更多錯別字,而這些解釋了意想不到的結果。有可能是這位藝術家的統計數據總和爲零。 –

回答

2

一些有趣的事情發生在這裏。

首先,您在ListingEventTest文件下保存ArtistTest,而不是作爲單獨的文件,所以在你的指數也沒有必要打電話給LoadDocument,你可能只是做:

from listingEvent in listingEvents 
from artist in listingEvent.Artists 
select ... 

第二,僅映射的,索引就像一個SQL索引,您只需調出想要查詢的列即可。在這裏,您正在對一組隱藏屬性進行計算,並且您有一個頂級屬性,您要在其中存儲該信息,但最終工作的方式是您的計算屬性值進入Lucene索引(因此您如果你願意,可以按熱門程度查詢),但是從未改變的文檔直接返回的數據是直接的。該地圖定義了Lucene的內容,它指向文檔ID,然後文檔存儲將文檔作爲結果返回。

這可以通過在索引的構造函數中調用Store(x => x.Popularity)進行修改,該函數將存儲稍後要調用的值,但老實說,我不確定您的計算值或文檔值(它是零)是否會贏。

鑑於這種情況,只有在試圖在索引過程中填充文檔屬性時纔會產生文檔屬性,這就是爲什麼通常有一個更好的選項來獲得表示映射狀態的類,然後執行AbstractIndexCreationTask<TDocument, TReduceResult>其中TReduceResult類只包含映射的結果,即NamePopularity列。

然後,當您從中進行查詢時,可以使用.ProjectFromIndexFieldsInto<T>()從存儲的索引結果中獲取結果,而不是從文檔存儲中獲取結果。

+0

對不起 - 它應該是DenormalizedReference iwayneo

+0

但這看起來現貨上 - 感謝您抽出寶貴:) – iwayneo

+0

嗯時間 - 我不能在lucenequery使用ProjectFromIndexFieldsInto – iwayneo