我希望能够收回所有包含我指定的所有标签的博文。
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 :(得分: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绑定,那么你可能想要按照自己的方式做事。