NEST 查询精确文本匹配

2024-02-18

我正在尝试编写一个 NEST 查询,该查询应根据精确的字符串匹配返回结果。我在网上研究过,有关于使用术语、匹配、匹配短语的建议。我已经尝试了所有这些,但我的搜索返回的结果包含部分搜索字符串。 例如,在我的数据库中,我有以下几行电子邮件地址:

[电子邮件受保护] /cdn-cgi/l/email-protection

[电子邮件受保护] /cdn-cgi/l/email-protection

[电子邮件受保护] /cdn-cgi/l/email-protection

无论我是否使用:

client.Search<Emails>(s => s.From(0)
                        .Size(MaximumSearchResultsSize)
                        .Query(q => q.Term( p=> p.OnField(fielname).Value(fieldValue))))

or

  client.Search<Emails>(s => s.From(0).
                              Size(MaximumPaymentSearchResults).
                              Query(q=>q.Match(p=>p.OnField(fieldName).Query(fieldValue))));                                              

我的搜索结果始终返回包含“部分搜索”字符串的行。

因此,如果我将搜索字符串提供为“ter”,我仍然会获得所有 3 行。[电子邮件受保护] /cdn-cgi/l/email-protection

[电子邮件受保护] /cdn-cgi/l/email-protection

[电子邮件受保护] /cdn-cgi/l/email-protection

如果搜索字符串是“ter”,我预计不会返回任何行。如果搜索字符串是“t[电子邮件受保护] /cdn-cgi/l/email-protection“那我只想看看”[电子邮件受保护] /cdn-cgi/l/email-protection".

不知道我做错了什么。


根据您在问题中提供的信息,听起来包含电子邮件地址的字段已被索引标准分析仪 https://www.elastic.co/guide/en/elasticsearch/reference/current/analysis-standard-analyzer.html,如果未指定其他分析器或该字段未标记为,则应用于字符串字段的默认分析器not_analyzed.

标准分析器对给定字符串输入的影响可以通过使用分析API https://www.elastic.co/guide/en/elasticsearch/reference/current/indices-analyze.html弹性搜索:

curl -XPOST "http://localhost:9200/_analyze?analyzer=standard&text=ter%40gmail.com

文本输入需要进行 url 编码,如此处使用 @ 符号所示。运行该查询的结果是

{
   "tokens": [
      {
         "token": "ter",
         "start_offset": 0,
         "end_offset": 3,
         "type": "<ALPHANUM>",
         "position": 1
      },
      {
         "token": "gmail.com",
         "start_offset": 4,
         "end_offset": 13,
         "type": "<ALPHANUM>",
         "position": 2
      }
   ]
}

我们可以看到标准分析器为输入生成两个标记,ter and gmail.com,这就是该字段的倒排索引中将存储的内容。

现在,运行一个Match query https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-match-query.html将导致分析匹配查询的输入,默认情况下使用与应用匹配查询的字段的映射定义中找到的分析器相同的分析器。

然后,默认情况下,将来自此匹配查询分析的结果组合成一个布尔值或查询使得包含该字段的倒排索引中的任何一个标记的任何文档都将是匹配的。举个例子

text [email protected] /cdn-cgi/l/email-protection,这意味着任何匹配的文档ter or gmail.com因为这个领域会很受欢迎

// Indexing
input: [email protected] /cdn-cgi/l/email-protection -> standard analyzer -> ter,gmail.com in inverted index

// Querying
input: [email protected] /cdn-cgi/l/email-protection -> match query -> docs with ter or gmail.com are a hit!

显然,对于精确匹配来说,这根本不是我们想要的!

运行一个Term query https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-query.html将导致术语查询的输入not被分析,即它是一个与术语输入完全匹配的查询,但在索引时已分析过的字段上运行它可能会出现问题;由于字段的值已经过分析,但术语查询的输入尚未经过分析,因此您将得到与索引时发生的分析结果与术语输入完全匹配的结果。例如

// Indexing
input: [email protected] /cdn-cgi/l/email-protection -> standard analyzer -> ter,gmail.com in inverted index

// Querying
input: [email protected] /cdn-cgi/l/email-protection -> term query -> No exact matches for [email protected] /cdn-cgi/l/email-protection

input: ter -> term query -> docs with ter in inverted index are a hit!

这也不是我们想要的!

我们可能想要对该字段执行的操作是将其设置为not_analyzed在映射定义中

putMappingDescriptor
    .MapFromAttributes()
    .Properties(p => p
        .String(s => s.Name(n => n.FieldName).Index(FieldIndexOption.NotAnalyzed)
    );

有了这个,我们就可以搜索精确匹配 with a Term filter https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-term-filter.html用一个Filtered query https://www.elastic.co/guide/en/elasticsearch/reference/current/query-dsl-filtered-query.html

// change dynamic to your type
var docs = client.Search<dynamic>(b => b
    .Query(q => q
        .Filtered(fq => fq
            .Filter(f => f
                .Term("fieldName", "[email protected] /cdn-cgi/l/email-protection")
            )
        )
    )
);

这将产生以下查询 DSL

{
  "query": {
    "filtered": {
      "filter": {
        "term": {
          "fieldName": "[email protected] /cdn-cgi/l/email-protection"
        }
      }
    }
  }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NEST 查询精确文本匹配 的相关文章

  • 查找哪些页面不再与写入时复制共享

    假设我在 Linux 中有一个进程 我从中fork 另一个相同的过程 后forking 因为原始进程将开始写入内存 Linux写时复制机制将为进程提供与分叉进程使用的不同的唯一物理内存页 在执行的某个时刻 我如何知道原始进程的哪些页面已被写
  • 迭代变量并查找特定类型实例的技术

    我想迭代进程中内存中的变量 通过插件动态加载 并查找特定类型的实例 以前我可以找到特定类型 或内存中的所有类型 我可以创建类型的实例 我可以获取作为不同类型的字段包含的实例 但我无论如何都不知道只是 搜索 特定类型的实例 一种方法是使用 W
  • 使用具有现有访问令牌的 Google API .NET 客户端

    用例如下 移动应用程序正在通过 Google 对用户进行身份验证 并且在某些时候 我们需要将用户的视频发布到他的 YouTube 帐户 出于实际原因 实际发布应该由后端完成 已经存储在那里的大文件 由于用户已经通过应用程序的身份验证 因此应
  • 如何创建可以像 UserControl 一样编辑的 TabPage 子类?

    我想创建一个包含一些控件的 TabPage 子类 并且我想通过设计器来控制这些控件的布局和属性 但是 如果我在设计器中打开子类 我将无法像在 UserControl 上那样定位它们 我不想创建一个带有 UserControl 实例的 Tab
  • 从 MVC 迁移到 ASP.NET Core 3.1 中的端点路由时,具有角色的 AuthorizeAttribute 不起作用

    我正在尝试将我的项目从 UseMVC asp net core 2 2 兼容样式 升级到 UseEndpoint Routing 并且我的所有请求都被重定向到我的验证失败页面 它与声明有关 如果我删除 Authorize Roles Adm
  • JSON 数组到 C# 列表

    如何将这个简单的 JSON 字符串反序列化为 C 中的列表 on4ThnU7 n71YZYVKD CVfSpM2W 10kQotV 这样 List
  • 从多个类访问串行端口

    我正在尝试使用串行端口在 arduino 和 C 程序之间进行通信 我对 C 编程有点陌生 该程序有多种用户控制形式 每一个都需要访问串口来发送数据 我需要做的就是从每个类的主窗体中写入串行端口 我了解如何设置和写入串行端口 这是我的 Fo
  • 当前的 c++ 工作草案与当前标准有何不同

    通过搜索该标准的 PDF 版本 我最终找到了这个链接C 标准措辞草案 http www open std org jtc1 sc22 wg21 docs papers 2012 n3376 pdf从 2011 年开始 我意识到我可以购买最终
  • 如何将“外部模板”与由同一类中的模板化成员使用的嵌套类一起使用?

    首先 一些背景信息 我尝试以 Herb Sutter 在他的解决方案中介绍的方式使用 Pimpl 习语 得到了 101 http herbsutter com gotw 101 这在头文件中看起来像这样 include pimpl h h
  • 在 2D 中将一个点旋转另一个点

    我想知道当一个点相对于另一个点旋转一定角度时如何计算出新的坐标 我有一个块箭头 想要将其相对于箭头底部中间的点旋转角度 theta 这是允许我在两个屏幕控件之间绘制多边形所必需的 我无法使用和旋转图像 从我到目前为止所考虑的情况来看 使问题
  • 在非活动联合成员上使用“std::addressof”是否定义明确[重复]

    这个问题在这里已经有答案了 下面的代码是尝试实现constexpr的版本offsetof在 C 11 中 它可以在 gcc 7 2 0 和 clang 5 0 0 中编译 这取决于申请std addressof工会非活跃成员的成员 这是明确
  • 当我“绘制”线条时,如何将点平均分配到 LineRenderer 的宽度曲线?

    我正在使用线条渲染器创建一个 绘图 应用程序 现在我尝试使用线条渲染器上的宽度曲线启用笔压 问题在于 AnimationCurve 的 时间 值 水平轴 从 0 标准化为 1 因此我不能在每次添加位置时都在其末尾添加一个值 除非有一个我不知
  • 尚未处理时调用 Form 的 Invoke 时出现 ObjectDisposeException

    我们得到一个ObjectDisposedException从一个电话到Invoke在尚未处理的表格上 这是一些演示该问题的示例代码 public partial class Form2 Form void Form2 Load object
  • g++ 对于看似不相关的变量“警告:迭代...调用未定义的行为”

    考虑以下代码strange cpp include
  • 在类的所有方法之前运行一个方法

    在 C 3 或 4 中可以做到这一点吗 也许有一些反思 class Magic RunBeforeAll public void BaseMethod runs BaseMethod before being executed public
  • 耐用功能是否适合大量活动?

    我有一个场景 需要计算 500k 活动 都是小算盘 由于限制 我只能同时计算 30 个 想象一下下面的简单示例 FunctionName Crawl public static async Task
  • 什么是 __declspec 以及何时需要使用它?

    我见过这样的例子 declspec在我正在阅读的代码中 它是什么 我什么时候需要使用这个构造 这是 Microsoft 对 C 语言的特定扩展 它允许您使用存储类信息来赋予类型或函数属性 文档 declspec C https learn
  • 转到定义:“无法导航到插入符号下的符号。”

    这个问题的答案是社区努力 help privileges edit community wiki 编辑现有答案以改进这篇文章 目前不接受新的答案或互动 我今天突然开始在我的项目中遇到一个问题 单击 转到定义 会出现一个奇怪的错误 无法导航到
  • WinRT 定时注销

    我正在开发一个 WinRT 应用程序 要求之一是应用程序应具有 定时注销 功能 这意味着在任何屏幕上 如果应用程序空闲了 10 分钟 应用程序应该注销并导航回主屏幕 显然 执行此操作的强力方法是在每个页面的每个网格上连接指针按下事件 并在触
  • 使用 Crypto++ 获取 ECDSA 签名

    我必须使用 Crypto 在变量中获取 ECDSA 签名 我在启动 SignMessage 后尝试获取它 但签名为空 我怎样才能得到它 你看过 Crypto wiki 吗 上面有很多东西椭圆曲线数字签名算法 http www cryptop

随机推荐