RavenDB 中的子字符串搜索

2024-03-08

我有一组类型的对象Idea

public class Idea
{
    public string Title { get; set; }
    public string Body { get; set; }
}

我想通过子字符串搜索这个对象。例如,当我有标题对象“idea“,我希望当我输入“的任何子字符串时都能找到它idea": 我、id、ide、想法、d、de、dea、e、ea、a.

我使用 RavenDB 来存储数据。搜索查询如下所示:

var ideas = session
              .Query<IdeaByBodyOrTitle.IdeaSearchResult, IdeaByBodyOrTitle>()
              .Where(x => x.Query.Contains(query))
              .As<Idea>()
              .ToList();

而索引如下:

public class IdeaByBodyOrTitle : AbstractIndexCreationTask<Idea, IdeaByBodyOrTitle.IdeaSearchResult>
{
    public class IdeaSearchResult
    {
        public string Query;
        public Idea Idea;
    }

    public IdeaByBodyOrTitle()
    {
        Map = ideas => from idea in ideas
                       select new
                           {
                               Query = new object[] { idea.Title.SplitSubstrings().Concat(idea.Body.SplitSubstrings()).Distinct().ToArray() },
                               idea
                           };
        Indexes.Add(x => x.Query, FieldIndexing.Analyzed);
    }
}

SplitSubstrings()是一个扩展方法,它返回给定字符串的所有不同子字符串:

static class StringExtensions
{
    public static string[] SplitSubstrings(this string s)
    {
        s = s ?? string.Empty;
        List<string> substrings = new List<string>();
        for (int i = 0; i < s.Length; i++)
        {                
            for (int j = 1; j <= s.Length - i; j++)
            {
                substrings.Add(s.Substring(i, j));
            }
        }            
        return substrings.Select(x => x.Trim()).Where(x => !string.IsNullOrEmpty(x)).Distinct().ToArray();
    }
}

这是行不通的。特别是因为 RavenDB 无法识别SplitSubstrings()方法,因为它在我的自定义程序集中。如何做到这一点,基本上如何强制 RavenDB 识别这种方法?除此之外,我的方法适合这种搜索(按子字符串搜索)吗?

EDIT

基本上,我想在此搜索上构建自动完成功能,因此它需要很快。

顺便说一句:我正在使用 RavenDB - Build #960


您可以使用以下方法跨多个字段执行子字符串搜索:

( 1 )

public class IdeaByBodyOrTitle : AbstractIndexCreationTask<Idea>
{
    public IdeaByBodyOrTitle()
    {
        Map = ideas => from idea in ideas
                       select new
                           {
                               idea.Title,
                               idea.Body
                           };
    }
}

on 这个网站 http://ravendb.net/docs/client-api/querying/static-indexes/configuring-index-options你可以检查一下:

“默认情况下,RavenDB 使用名为 适用于所有内容的 LowerCaseKeywordAnalyzer。 (...) 默认值 每个字段是 Stores 中的 FieldStorage.No 和 FieldIndexing.Default 中的 索引。”

因此,默认情况下,如果您检查 raven 客户端内的索引术语,它看起来如下:

Title                    Body
------------------       -----------------
"the idea title 1"       "the idea body 1"
"the idea title 2"       "the idea body 2" 

在此基础上,可以构造通配符查询:

var wildquery = string.Format("*{0}*", QueryParser.Escape(query));

然后与使用.In and .Where结构(内部使用 OR 运算符):

var ideas = session.Query<User, UsersByDistinctiveMarks>()
                   .Where(x => x.Title.In(wildquery) || x.Body.In(wildquery));

( 2 )

或者,您可以使用纯 lucene 查询:

var ideas = session.Advanced.LuceneQuery<Idea, IdeaByBodyOrTitle>()
                   .Where("(Title:" + wildquery + " OR Body:" + wildquery + ")");

( 3 )

您还可以使用.Search表达式,但如果您想跨多个字段进行搜索,则必须以不同的方式构建索引:

public class IdeaByBodyOrTitle : AbstractIndexCreationTask<Idea, IdeaByBodyOrTitle.IdeaSearchResult>
{
    public class IdeaSearchResult
    {
        public string Query;
        public Idea Idea;
    }

    public IdeaByBodyOrTitle()
    {
        Map = ideas => from idea in ideas
                       select new
                           {
                               Query = new object[] { idea.Title, idea.Body },
                               idea
                           };
    }
}

var result = session.Query<IdeaByBodyOrTitle.IdeaSearchResult, IdeaByBodyOrTitle>()
                    .Search(x => x.Query, wildquery, 
                            escapeQueryOptions: EscapeQueryOptions.AllowAllWildcards,
                            options: SearchOptions.And)
                    .As<Idea>();

summary:

还要记住*term*相当昂贵,尤其是前导通配符。在这个post http://daniellang.net/searching-on-string-properties-in-ravendb/你可以找到更多相关信息。据说,前导通配符会强制 lucene 对索引进行全面扫描,从而大大降低查询性能。 Lucene 在内部存储按字母顺序排序的索引(实际上是字符串字段的术语)并从左到右“读取”。这就是为什么搜索尾随通配符很快而搜索前导通配符很慢的原因。

所以或者x.Title.StartsWith("something")可以使用,但这显然不会搜索所有子字符串。如果您需要快速搜索,您可以更改要分析的搜索字段的“索引”选项,但它不会再次搜索所有子字符串。

如果有一个子字符串查询内的空格键,请检查这个question https://stackoverflow.com/questions/12298468/search-by-substring-with-spacebar-in-ravendb以获得可能的解决方案。 如需提出建议,请检查http://architects.dzone.com/articles/how-do-suggestions-ravendb http://architects.dzone.com/articles/how-do-suggestions-ravendb.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

RavenDB 中的子字符串搜索 的相关文章

  • 如何在列表框项目之间画一条线

    我希望能够用水平线分隔列表框中的每个项目 这只是我用于绘制项目的一些代码 private void symptomsList DrawItem object sender System Windows Forms DrawItemEvent
  • 使闭包捕获的变量变得易失性

    闭包捕获的变量如何与不同线程交互 在下面的示例代码中 我想将totalEvents 声明为易失性的 但C 不允许这样做 是的 我知道这是错误的代码 这只是一个例子 private void WaitFor10Events volatile
  • WPF 中的调度程序和异步等待

    我正在尝试学习 WPF C 中的异步编程 但我陷入了异步编程和使用调度程序的困境 它们是不同的还是在相同的场景中使用 我愿意简短地回答这个问题 以免含糊不清 因为我知道我混淆了 WPF 中的概念和函数 但还不足以在功能上正确使用它 我在这里
  • 指针问题(仅在发布版本中)

    不确定如何描述这一点 但我在这里 由于某种原因 当尝试创建我的游戏的发布版本进行测试时 它的敌人创建方面不起作用 Enemies e level1 3 e level1 0 Enemies sdlLib 500 2 3 128 250 32
  • 在.rdlc报告的底部设置一个文本框

    我在 rdlc 报告中使用 tablix 有一个文本框 其中包含文本 签名 我想将此文本框放置在报告最后一页的底部 就在页脚之前 我已经用谷歌搜索了这个解决方案 但没有找到满意的结果 我的环境是VS2010 framework 4 0 有什
  • 如果使用 SingleOrDefault() 并在数字列表中搜索不在列表中的数字,如何返回 null?

    使用查询正数列表时SingleOrDefault 当在列表中找不到数字时 如何返回 null 或像 1 这样的自定义值 而不是类型的默认值 在本例中为 0 你可以使用 var first theIntegers Cast
  • Qt moc 在头文件中实现?

    是否可以告诉 Qt MOC 我想声明该类并在单个文件中实现它 而不是将它们拆分为 h 和 cpp 文件 如果要在 cpp 文件中声明并实现 QObject 子类 则必须手动包含 moc 文件 例如 文件main cpp struct Sub
  • 使用 System.Text.Json 即时格式化 JSON 流

    我有一个未缩进的 Json 字符串 例如 hash 123 id 456 我想缩进字符串并将其序列化为 JSON 文件 天真地 我可以使用缩进字符串Newtonsoft如下 using Newtonsoft Json Linq JToken
  • 在 ASP.NET Core 3.1 中使用包含“System.Web.HttpContext”的旧项目

    我们有一些用 Net Framework编写的遗留项目 应该由由ASP NET Core3 1编写的API项目使用 问题是这些遗留项目正在使用 System Web HttpContext 您知道它不再存在于 net core 中 现在我们
  • Discord.net 无法在 Linux 上运行

    我正在尝试让在 Linux VPS 上运行的 Discord net 中编码的不和谐机器人 我通过单声道运行 但我不断收到此错误 Unhandled Exception System Exception Connection lost at
  • 如何在 VBA 中声明接受 XlfOper (LPXLOPER) 类型参数的函数?

    我在之前的回答里发现了问题 https stackoverflow com q 19325258 159684一种无需注册即可调用 C xll 中定义的函数的方法 我之前使用 XLW 提供的注册基础结构 并且使用 XlfOper 类型在 V
  • C++ fmt 库,仅使用格式说明符格式化单个参数

    使用 C fmt 库 并给定一个裸格式说明符 有没有办法使用它来格式化单个参数 example std string str magic format 2f 1 23 current method template
  • C - 直接从键盘缓冲区读取

    这是C语言中的一个问题 如何直接读取键盘缓冲区中的数据 我想直接访问数据并将其存储在变量中 变量应该是什么数据类型 我需要它用于我们研究所目前正在开发的操作系统 它被称为 ICS OS 我不太清楚具体细节 它在 x86 32 位机器上运行
  • 有没有办法禁用 .NET 标签的“双击复制”功能?

    这真的很烦人 我使用标签作为列表项用户控件的一部分 用户可以单击它来选择列表项 然后双击它来重命名它 但是 如果剪贴板中有名称 双击标签会将其替换为标签文本 我还检查了应用程序中的其他标签 双击它们也会将其复制到剪贴板 我没有在这个程序中编
  • 32 位到 64 位内联汇编移植

    我有一段 C 代码 在 GNU Linux 环境下用 g 编译 它加载一个函数指针 它如何执行并不重要 使用一些内联汇编将一些参数推送到堆栈上 然后调用该函数 代码如下 unsigned long stack 1 23 33 43 save
  • const、span 和迭代器的问题

    我尝试编写一个按索引迭代容器的迭代器 AIt and a const It两者都允许更改容器的内容 AConst it and a const Const it两者都禁止更改容器的内容 之后 我尝试写一个span
  • x86 上未对齐的指针

    有人可以提供一个示例 将指针从一种类型转换为另一种类型由于未对齐而失败吗 在评论中这个答案 https stackoverflow com questions 544928 reading integer size bytes from a
  • 如何使用 std::string 将所有出现的一个字符替换为两个字符?

    有没有一种简单的方法来替换所有出现的 in a std string with 转义 a 中的所有斜杠std string 完成此操作的最简单方法可能是boost字符串算法库 http www boost org doc libs 1 46
  • ASP.NET MVC 6 (ASP.NET 5) 中的 Application_PreSendRequestHeaders 和 Application_BeginRequest

    如何在 ASP NET 5 MVC6 中使用这些方法 在 MVC5 中 我在 Global asax 中使用了它 现在呢 也许是入门班 protected void Application PreSendRequestHeaders obj
  • 恢复上传文件控制

    我确实阅读了以下帖子 C 暂停 恢复上传 https stackoverflow com questions 1048330 pause resume upload in c 使用 HTTP 恢复上传 https stackoverflow

随机推荐

  • Java 的 java.util.concurrent 包在 .NET 中的等价物是什么?

    我有 Java 背景 我想了解有关 Net 和 C 中并发性的更多信息 有没有类似Java的concurrent utils包的东西 最接近的是 NET 4 0 中的新线程功能 也称为并行扩展 NET 的现有功能 即 3 5 及更早版本 优
  • 同一 data.frame 中的分组/重新编码因素

    假设我有一个像这样的数据框 df lt data frame a letters 1 26 1 26 我想将 a b 和 c 重新 因子为 a 我怎么做 一种选择是recode 包中的函数car require car df lt data
  • PHP中下个月日期时间戳的最后一天? [复制]

    这个问题在这里已经有答案了 我正在使用以下函数来获取当前时间戳 created timestamp date Y m d H i s 但是我如何获得下个月最后一天的时间戳 例如 如果是 9 月 15 日 则获得 10 月 31 日 包括所有
  • 如何为 Chart.js (chartjs.org) 中的所有图表类型添加标签/图例?

    Chart js 的文档提到了 图例模板 但没有提供此类图例的资源或示例 这些如何显示呢 您可以在图表选项中包含图例模板 legendTemplate takes a template as a string you can populat
  • Electron 中渲染器和主进程的区别

    我最初认为 Electron 中的渲染器进程是在类似 chrome 的环境中沙箱化的 这意味着你所能做的就是弄乱 DOM 但是 我最近了解到您可以访问文件系统 运行子进程并获取其输出 以及导入您想要的任何其他节点模块 如果是这样的话 主进程
  • 如何使用 Javascript 将数组拆分为基于值的多个数组?

    我有一个数组 我想根据值 完成 将其拆分为多个数组 当我找到它时 我拆分数组 我的代码是 var input urlGettingF BROKEN aquaHTTP 404 BROKEN url1HTTP 404 ok urlok Fini
  • 提高 html canvas mousemove 图像蒙版的性能

    我有一个画布 正在绘制图像并进行剪辑以创建图像被显示的效果 我的代码工作正常 我尝试使用 debouce 方法和 rAF 来提高画布渲染性能 但我只看到了很小的收益 如果有的话 我怀疑我迭代 x 和 y 坐标数组的方式可能是问题所在 当将数
  • Flutter - JSON 和时间序列图表

    我试图在时间序列图表中显示一些数据 我找到了一个例子 https google github io charts flutter example time series charts simple html https google git
  • 找到一条经过最大点数的线[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 创建机器人时出错

    我在创建机器人时遇到错误 我正在尝试部署一个网络应用程序机器人 指定资源组的名称及其位置后 我单击 创建 之后机器人部署过程开始 但最终会出现错误 MsaAppId MsaAppId 已在使用中 我可以做什么来成功部署基本机器人 这是一周内
  • 按一列分组,为每对列选择一列中最小值的行

    很难说清楚的问题 这是我想做的一个例子 我开始的一个例子 set seed 0 dt lt data table dr1 d rnorm 5 dr1 p abs rnorm 5 sd 0 08 dr2 d rnorm 5 dr2 p abs
  • 使用 Python 更改控制台窗口的位置 (Windows)

    是否可以通过python改变Windows控制台的位置 如果没有 有什么解决方法吗 我不知道您是否需要任何具体信息 但以防万一 我使用的是 Windows 8 1 64x Python 3 5 0 控制台是通过Popen主要目标是将其移动到
  • 如何使用用例关系 - uml

    嘿伙计们 我一直在研究 UML 并且正在尝试设计问题的用例图 假设我的应用程序包含以下内容 两个要求 创建团队 创建玩家 这是这笔交易 用户可以创建一个球队 创建球队后可以为该球队创建球员 非必需 但在这个应用程序中有多个用户 一个用户可以
  • 将Django模型父类添加到现有模型中以实现多表继承

    The Django 文档 https docs djangoproject com en 1 9 topics db models multi table inheritance使用此示例来演示多表继承 from django db im
  • LINQ查询中的自连接并返回视图

    我正在使用 LINQ 自联接查询在视图上显示数据 我的 sql 表包含一些员工详细信息 我需要显示员工详细信息及其经理姓名 因为它是表中的 ManagerID EmpID Name ManagerID Designation Phone A
  • “导出声明类型 Xyz”与“导出类型 Xyz”中的声明意味着什么

    在定义文件中 写入以下两者是有效的 export declare type Abc string export type Bcd string The declare这里的关键字没有任何作用 对吗 正确的 declare当您需要说明执行时会
  • Visual Studio 2017状态栏颜色

    VS2017 至少是我刚刚安装的最新更新 在主窗口的底部有一个闪亮的蓝色状态栏 在视觉上非常突出 由于这是整个屏幕上唯一的大亮蓝色物体 因此非常分散注意力 有没有办法改变颜色 根据这个答案 https stackoverflow com q
  • 如何从 android studio 发出拉取请求?

    我将应用程序分叉到 android studio 当我尝试发出拉取请求时 I get Can t Create Pull Request Push failed failed to push some refs to https githu
  • 如何在一种解决方案中调试/单元测试 Web APi

    有没有一种方法可以在一个解决方案中对 Web api 进行单元测试或调试 我正在使用 HttpClient 使用 WebAPI 并且有两个 VS 实例来执行此操作 在 1 个 VS 实例中 我进行了单元测试 在第二个 VS 实例中 我在 l
  • RavenDB 中的子字符串搜索

    我有一组类型的对象Idea public class Idea public string Title get set public string Body get set 我想通过子字符串搜索这个对象 例如 当我有标题对象 idea 我希