2013-02-12 43 views
5

我有一個文件結構如下所示:RavenDb靜態指標:在孩子收集查詢對象

Employer => Positions => RequiredSkills

發包方位置
位置有RequiredSkill集合的集合。
必需技能由技能(字符串)和熟練(枚舉)組成。

如果我使用動態索引它似乎返回公司罰款,但是我想使用索引來填充MVC視圖模型返回到用戶界面。

我真的很新來烏鴉,所以我很抱歉做任何愚蠢/不必要的事!

我有以下映射:

public class PositionSearch : AbstractIndexCreationTask<Employer> 
    { 
     public PositionSearch() 
     { 
      Map = employers => 
        from employer in employers 
        from position in employer.Positions 
        select new 
         { 
          EmployerId = employer.Id, 
          EmployerName = employer.Name, 
          PositionId = position.Id, 
          PositionTitle = position.Title, 
          position.Location, 
          position.Description, 
          RequiredSkills = position.RequiredSkills 
         }; 

      StoreAllFields(FieldStorage.Yes); 

      Index("RequiredSkills_Skill", FieldIndexing.Analyzed); 
     } 
    } 

然而,當我嘗試執行以下查詢:

var results = session.Query<PositionSearchResultModel, PositionSearch>() 
    .Customize(x => x.WaitForNonStaleResults()) 
    .Where(x=>x.RequiredSkills.Any(y=>y.Skill == "SkillName")) 
    .ProjectFromIndexFieldsInto<PositionSearchResultModel>() 
    .ToList(); 

我得到以下錯誤:

System.ArgumentException: 
    The field 'RequiredSkills_Skill' is not indexed, 
    cannot query on fields that are not indexed 

燦任何人看到我在做什麼錯誤或爲我建議另一種方法?

感謝,

詹姆斯

更新我的視圖模型 - 感謝:

public class PositionSearchResultModel 
{ 
    public PositionSearchResultModel() 
    { 
     RequiredSkills = new HashSet<SkillProficiency>(); 
    } 

    public string EmployerId { get; set; } 
    public string EmployerName { get; set; } 
    public string PositionId { get; set; } 
    public string PositionTitle { get; set; } 
    public string Location { get; set; } 
    public string Description { get; set; } 
    public ICollection<SkillProficiency> RequiredSkills { get; set; } 
} 
+0

您將索引條目與索引結果混淆。請提供您的'PositionSearchResultModel'類,我將回答一個完整的解決方案。謝謝。 – 2013-02-12 15:00:45

+0

添加了我的視圖模型。 – Jamez 2013-02-12 15:10:17

+0

我看到你試圖標記分析的領域。你想要在技能名稱上完全匹配嗎?或者你想進行分析搜索? – 2013-02-12 15:41:16

回答

8

因爲你想要做對技能名稱的分析搜索,你需要把它分離爲一個單獨的索引條目。

public class PositionSearch 
    : AbstractIndexCreationTask<Employer, PositionSearchResultModel> 
{ 
    public PositionSearch() 
    { 
     Map = employers => 
       from employer in employers 
       from position in employer.Positions 
       select new 
       { 
        EmployerId = employer.Id, 
        EmployerName = employer.Name, 
        PositionId = position.Id, 
        PositionTitle = position.Title, 
        position.Location, 
        position.Description, 
        position.RequiredSkills, 

        // Isolate the search property into it's own value 
        SkillsSearch = position.RequiredSkills.Select(x => x.Skill) 
       }; 

     // you could store all fields if you wanted, but the search field 
     // doesn't need to be stored so that would be wasteful. 
     Store(x => x.PositionId, FieldStorage.Yes); 
     Store(x => x.PositionTitle, FieldStorage.Yes); 
     Store(x => x.Location, FieldStorage.Yes); 
     Store(x => x.Description, FieldStorage.Yes); 
     Store(x => x.RequiredSkills, FieldStorage.Yes); 

     // Any field you are going to use .Search() on should be analyzed. 
     Index(x => x.SkillsSearch, FieldIndexing.Analyzed); 
    } 
} 

請注意,我指定投影作爲索引的結果。這是句法糖。將它關閉是沒有問題的,但是必須使用字符串指定搜索字段。

您還需要在搜索字段添加到您的結果類

public string[] SkillsSearch { get; set; } 

這真的不要緊它是什麼類型。一個字符串數組或集合將會很好。你也可以只使用一個字符串或一個對象,因爲它只是相關的名字。

當查詢針對此索引,使用.Search()方法,像這樣:

var results = session.Query<PositionSearchResultModel, PositionSearch>() 
    .Customize(x => x.WaitForNonStaleResults()) // only use this in testing 
    .Search(x=> x.SkillsSearch, "SkillName") 
    .ProjectFromIndexFieldsInto<PositionSearchResultModel>() // AsProjection would also work 
    .ToList(); 

請注意,您必須存儲許多領域的唯一原因是因爲要投影他們。如果你把職位分成他們自己的文件,你會有更小的索引,更少的項目。請記住,當您投影時,原始文檔中的所有字段都已經存在並直接來自文檔存儲區,而不必複製到索引中。因此,如果您的原始文檔更符合您的預期結果,那麼您的工作量就會減少。

+0

我需要做類似的事情,但我不需要查看結果,只需檢查技能是否存在即可。這是否意味着我不需要存儲這些字段? – codedog 2013-10-07 18:54:13

+1

@DanyW - 如果您只是使用where子句中的字段,則不需要存儲它們。如果您要將它們投影回結果集,則只需要存儲它們。 – 2013-10-07 19:15:30