c# - RavenDB - 查询具有多个术语的集合

标签 c# nosql 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();
        }
    }
}

最佳答案

唯一的问题是,由于您正在进行单元测试,因此您需要在写入数据和检查索引之间明确留出时间。否则,您的索引已过时。参见 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,那么您可能想按照自己的方式做事。

关于c# - RavenDB - 查询具有多个术语的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16421193/

相关文章:

c# - 使用 linq 获取分组的逗号分隔值

c# - 如何调用 aspx 页面并让它返回图像?

c# - 过滤器是否可以替换使用 c# 的 mongo 查询中的查询?

RavenDB 复制问题

c# - 在 RavenDb 中映射减少 2 个带有子集合的集合

c# - RavenDB Map Reduce 非重复索引

c# - 统一下载后如何检查可寻址 Assets 或场景是否被缓存?

mongodb - 合并 RDBMS 和 NoSQL 数据库

laravel - MongoDB 在数组中搜索嵌套对象

c# - AssemblyLoadContext 是否隔离静态变量?