2013-02-12 42 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