2013-02-12 31 views
5

Tôi có một cấu trúc tài liệu như sau:RavenDb Index tĩnh: truy vấn trên bộ sưu tập con các đối tượng

Employer => Positions => RequiredSkills

tuyển dụng có một tập hợp các vị trí
Positions có một bộ sưu tập của RequiredSkill.
Kỹ năng bắt buộc bao gồm kỹ năng (chuỗi) và thành thạo (enum).

Nếu tôi sử dụng chỉ mục động, dường như nó sẽ trả về tiền phạt của công ty, tuy nhiên tôi muốn sử dụng chỉ mục để điền các kiểu xem MVC để quay lại giao diện người dùng.

Tôi thực sự mới đối với Raven nên tôi xin lỗi vì đã làm bất cứ điều gì ngu ngốc/không cần thiết!

Tôi đã có các bản đồ sau:

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

Tuy nhiên khi tôi cố gắng thực hiện các truy vấn sau đây:

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

tôi nhận được lỗi sau:

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

Can bất cứ ai nhìn thấy những gì tôi đang làm sai hoặc đề nghị một cách tiếp cận cho tôi xin vui lòng?

Cảm ơn,

James

CẬP NHẬT mô hình quan điểm của tôi - Cảm ơn:

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

Bạn đang nhầm lẫn các mục nhập chỉ mục với kết quả chỉ mục. Vui lòng cung cấp lớp 'PositionSearchResultModel' của bạn và tôi sẽ trả lời bằng một giải pháp hoàn chỉnh. Cảm ơn. –

+0

Đã thêm mô hình chế độ xem của tôi. – Jamez

+0

Tôi thấy bạn đang cố đánh dấu trường như được phân tích. Bạn có muốn kết hợp chính xác tên kỹ năng không? Hay bạn muốn thực hiện tìm kiếm được phân tích? –

Trả lời

8

Bởi vì bạn muốn làm một tìm kiếm phân tích so với tên kỹ năng, bạn cần phải cô lập nó như là một mục chỉ mục riêng biệt.

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

Lưu ý rằng tôi đã chỉ định phép chiếu làm kết quả của chỉ mục. Đây là cú pháp. Nó không phải là sai để để nó đi, nhưng sau đó bạn phải xác định lĩnh vực tìm kiếm của bạn bằng cách sử dụng một chuỗi.

Bạn cũng sẽ cần phải thêm lĩnh vực tìm kiếm để kết quả lớp học của bạn

public string[] SkillsSearch { get; set; } 

Nó thực sự không có vấn đề gì loại nó được. Một mảng chuỗi hoặc bộ sưu tập sẽ làm tốt. Bạn cũng có thể sử dụng chỉ một chuỗi hoặc một đối tượng, bởi vì nó chỉ là tên có liên quan.

Khi bạn truy vấn đối với chỉ số này, sử dụng phương pháp .Search(), như thế này:

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

Lưu ý rằng lý do duy nhất bạn phải lưu trữ rất nhiều các lĩnh vực là bởi vì bạn muốn dự án họ. Nếu bạn tách các vị trí thành các tài liệu của riêng mình, bạn sẽ có nhiều chỉ mục nhỏ hơn và ít nhiều hơn để dự án. Hãy nhớ rằng khi bạn dự án, tất cả các trường trong tài liệu gốc đã có sẵn và đến trực tiếp từ kho lưu trữ tài liệu, thay vì phải được sao chép vào chỉ mục. Vì vậy, nếu tài liệu gốc của bạn kết hợp chặt chẽ hơn với kết quả mong muốn của bạn, thì có ít việc phải làm hơn.

+0

Tôi cần phải làm một cái gì đó tương tự như thế này, nhưng tôi không cần phải xem kết quả, chỉ cần kiểm tra xem một kỹ năng là hiện tại. Điều đó có nghĩa là tôi không cần phải lưu trữ các lĩnh vực đó? – codedog

+1

@DanyW - Nếu bạn chỉ sử dụng các trường trong mệnh đề where, bạn không cần lưu trữ chúng. Chúng chỉ cần được lưu trữ nếu bạn định chiếu chúng trở lại tập kết quả của bạn. –

Các vấn đề liên quan