2013-02-12 6 views
5

aşağıdaki gibi bir belge yapıya sahip nesneler.
Zorunlu Beceri bir beceri (string) ve bir uzmanlıktan (enum) oluşur.RavenDb statik İndeksi:</p> <p><code>Employer => Positions => RequiredSkills</code></p> <p>İşveren <br> Pozisyonlar RequiredSkill bir koleksiyona sahip Pozisyon bir koleksiyona sahiptir: çocuk koleksiyonu sorgu

Dinamik bir dizin kullanırsam, şirkete iyi gelir, ancak MVC görünüm modellerini UI'ye döndürmek için bir dizin kullanmak istiyorum.

Gerçekten çok yeni Raven için çok aptalca/gereksiz bir şey yapmaktan dolayı özür dilerim! Ancak

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

aşağıdaki sorguyu çalıştırmayı:

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

aşağıdaki hatayı alıyorum:

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

Can

aşağıdaki eşleme var Herkes yanlış yaptığımı görüyor ya da benim için başka bir yaklaşım öneriyor mu?

sayesinde

James

GÜNCELLEME benim bakış modeli - Teşekkürler:

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

Dizin girişlerini dizin sonuçlarıyla karıştırıyorsunuz. Lütfen "PositionSearchResultModel" sınıfınızı sağlayın ve eksiksiz bir çözümle cevaplayacağım. Teşekkürler. –

+0

Ekleme modelim eklendi. – Jamez

+0

Analiz edilen alanı işaretlemeye çalıştığınızı görüyorum. Yetenek adına tam bir eşleşme mi istiyorsun? Veya analiz edilmiş bir arama yapmak mı istiyorsunuz? –

cevap

8

Eğer beceri adıyla karşı bir analiz arama yapmak istediğimiz için, siz onu izole etmek gerek ayrı bir dizin girişi.

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

Dizininin sonucu olarak projeksiyonu belirttiğimi unutmayın. Bu sözdizimsel şeker. Onu bırakmak yanlış değildir, ancak arama alanınızı bir dize kullanarak belirtmeniz gerekir.

Ayrıca sonuçlar sınıfta

public string[] SkillsSearch { get; set; } 

Gerçekten ne olduğunu türü önemli değildir arama alanı eklemek gerekir. Bir dize dizisi veya koleksiyonu iyi sonuç verecektir. Sadece bir dize veya bir nesneyi de kullanabilirsiniz, çünkü sadece alakalı olan isimdir.

Bu endeks karşı sorgulamak

, bu gibi .Search() yöntemi kullanın: Bunları yansıtmak istediğiniz çünkü oldukça fazla alan saklamak zorunda tek nedeni

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

Not söyledi. Eğer pozisyonları kendi belgelerine ayırdıysanız, çok daha küçük indekslere sahip olacak ve çok daha az proje yapacaksınız. Yansıtma yaptığınızda, orijinal belgedeki tüm alanların zaten var ve dizin içine kopyalanmak yerine doğrudan belge deposundan geldiğine dikkat edin. Dolayısıyla, orijinal belgeleriniz istenen sonuçlarla daha yakından eşleşiyorsa, yapılacak daha az iş vardır.

+0

Buna benzer bir şey yapmam gerekiyor, ancak sonucu görmem gerekmiyor, sadece bir Beceri olup olmadığını kontrol et. Bu, bu alanları saklamak zorunda olmadığım anlamına mı geliyor? – codedog

+1

@DanyW - Alanları yalnızca bir yan cümlede kullanıyorsanız, bunları saklamanız gerekmez. Sadece sonuç kümenize geri yansıtacaksanız saklanmaları gerekiyor. –

İlgili konular