2013-05-07 4 views
1

내가 지정한 모든 태그가있는 모든 블로그 게시물을 다시 가져오고 싶습니다.RavenDB - 여러 용어로 컬렉션 쿼리하기

public class Post 
{ 
    public int Name { get; set; } 
    public List<string> Tags { get; set; } 
} 

'C#'및 'html'태그가있는 모든 게시물을 가져오고 싶습니다.

이 예제는 내 예제와 똑같은 질문입니다. Linq query with multiple Contains/Any for RavenDB

태그에 'C#'및 'html'이 포함 된 게시물이 하나있는 경우 아래 예제에서 결과가 반환되지 않는 이유를 알고 싶습니다.

사람이 이상적으로 강력한 형식의 쿼리 구문의 예

var query = s.Query<Entity, IndexClass>() 

으로, 지금이 문제를 해결하기 위해 새로운, 더 우아한 방법이 있는지에 빛을 흘릴 수 있다면 그것은 좋은 것입니다 -

using System.Collections.Generic; 
using System.Linq; 
using NUnit.Framework; 
using Raven.Abstractions.Indexing; 
using Raven.Client.Embedded; 
using Raven.Client.Indexes; 

namespace RavenDB 
{ 
    public class Blog 
    { 
     public string Name { get; set; } 
     public List<string> Tags { get; set; } 
    } 

    public class BlogsByTags : AbstractIndexCreationTask<Blog> 
    { 
     public BlogsByTags() 
     { 
      Map = docs => from doc in docs 
          select new 
           { 
            Tags = doc.Tags 
           }; 

      Index(x => x.Tags, FieldIndexing.Analyzed); 
     } 
    } 

    [TestFixture] 
    public class Runner : UsingEmbeddedRavenStore 
    { 
     [Test] 
     public void Run() 
     { 
      Open(); 
      IndexCreation.CreateIndexes(typeof(BlogsByTags).Assembly, Store); 

      var blogs = new List<Blog> 
       { 
        new Blog{Name = "MVC", Tags = new List<string>{"html","c#"}}, 
        new Blog{Name = "HTML5", Tags = new List<string>{"html"}}, 
        new Blog{Name = "Version Control", Tags = new List<string>{"git"}}, 
       }; 

      using (var session = Store.OpenSession()) 
      {    
       foreach (var blog in blogs) 
       { 
        session.Store(blog); 
       } 
       session.SaveChanges(); 
      } 

      var tags = new List<string> { "c#", "html" }; 

      List<Blog> blogQueryResults; 

      using (var s = Store.OpenSession()) 
      { 

       blogQueryResults = s.Advanced.LuceneQuery<Blog, BlogsByTags>() 
        .Where(string.Format("Tags:({0})", string.Join(" AND ", tags))).ToList();     
      } 

      Assert.AreEqual(1, blogQueryResults.Count()); 
     } 
    } 

    public abstract class UsingEmbeddedRavenStore 
    { 
     protected EmbeddableDocumentStore Store { get; set; } 

     protected void Open() 
     { 
      Store = new EmbeddableDocumentStore 
      { 
       RunInMemory = 
        true 
      }; 

      Store.Initialize(); 
     } 

     protected void Dispose() 
     { 
      Store.Dispose(); 
     } 
    } 
} 
+0

어딘가에 질문이 있습니까? 귀하의 질문을 뒷받침하는 부분으로 귀하의 코드를 줄이고 질문을 명확하게하십시오. 감사. –

+0

불명확 한 질문에 사과를 해주셔서 감사합니다. 블로그 포스트/태그를 사용하여 질문을 명확하게하고 코드를 삭제하여 관련된 측면 만 표시하도록 재 작성했습니다. – CountZero

답변

4

단 하나의 문제는 단위 테스트를 수행 중이므로 데이터를 쓰고 인덱스를 확인할 때까지 명시 적으로 시간을 허용해야한다는 것입니다. 그렇지 않으면 색인이 오래되었습니다. these docs을 참조하십시오.

s.Advanced.LuceneQuery<Blog, BlogsByTags>() 

// Unit tests should wait explicitly. 
// Don't do this outside of a unit test. 
.WaitForNonStaleResults() 

.Where(string.Format("Tags:({0})", string.Join(" AND ", tags))) 

또한 고급 lucene 구문을 사용하지 않고 동일한 쿼리를 수행하는 방법을 물었습니다. 당신은 같이 .Search 확장 방법을 사용 할 수 있습니다 :

s.Query<Blog, BlogsByTags>() 
.Customize(x => x.WaitForNonStaleResults()) 
.Search(x => x.Tags, string.Join(" AND ", tags)) 

변경해야 한 가지가있다. 단위 테스트를 수행 할 때 단위 테스트가 인덱스를 위해 어셈블리를 스캔하는 것을 원하지 않습니다. 다른 테스트를 위해 작성된 색인을 선택할 수 있습니다.

// Instead of scanning like this 
IndexCreation.CreateIndexes(typeof(BlogsByTags).Assembly, store); 

// Create the single index like this 
store.ExecuteIndex(new BlogsByTags()); 

그리고 마지막으로, 나는 당신이 당신의 테스트를 단순화하는 데 사용할 수있는 RavenDB.Tests.Helpers nuget 패키지를 지적하고 싶습니다. 그것은 당신을위한 설치 작업을 많이 않습니다. 그것은 XUnit을 사용합니다 - 그래서 당신이 NUnit에 묶여 있다면 당신은 당신 자신의 방식으로 일을하고 싶어 할 것입니다.

+0

자세한 답변을 주셔서 감사합니다. – CountZero

관련 문제