当前位置: 首页 > 面试题库 >

NEST查询以精确匹配文本

郗河
2023-03-14
问题内容

我正在尝试编写一个NEST查询,该查询应基于完全匹​​配的字符串返回结果。我已经在网络上进行了研究,并且对使用术语,匹配,匹配短语有一些建议。我已经尝试了所有这些方法,但是搜索返回的结果中包含搜索字符串的一部分。例如,在我的数据库中,我有以下几行电子邮件地址:

ter@gmail.com

ter@hotmail.com

terrance@hotmail.com

无论我是否使用:

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

要么

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

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

因此,如果我将搜索字符串提供为“ ter”,则仍会得到所有3行。ter@gmail.com

ter@hotmail.com

terrance@hotmail.com

如果搜索字符串为“ ter”,我希望看不到返回的行。如果搜索字符串为“ ter@hotmail.com”,那么我只希望看到“
ter@hotmail.com”。

不知道我在做什么错。


问题答案:

根据问题中提供的信息,听起来好像包含电子邮件地址的字段已用 Standard
Analyzer
索引,如果未指定其他分析器或未将字段标记为,则默认的分析器应用于字符串字段not_analyzed

通过使用Elasticsearch 的 Analyze
API
,可以看到标准分析器对给定字符串输入的影响:

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和生成了两个标记gmail.com,这将存储在字段的倒排索引中。

现在,运行 匹配
查询将导致对
匹配
查询的输入进行分析,默认情况下,使用与在其中应用匹配查询的字段的映射定义中找到的分析器相同的分析器。

然后,默认情况下,将从此匹配查询分析得到的标记组合到 布尔值或 查询中,这样,包含该字段的反向索引中包含任何标记的任何文档都是匹配项。举个例子

text ter@gmail.com,这意味着与该字段匹配ter或匹配的任何文档gmail.com都会被点击

// Indexing
input: ter@gmail.com -> standard analyzer -> ter,gmail.com in inverted index

// Querying
input: ter@gmail.com -> match query -> docs with ter or gmail.com are a hit!

显然,对于完全匹配,这根本不是我们想要的!

运行 术语
查询将导致
分析术语查询的输入,即,它是对与术语输入完全匹配的查询,但是在索引时间已分析的字段上运行此查询可能会成为问题;由于已对该字段的值进行了分析,但尚未对术语查询进行输入,因此您将获得返回的结果,该结果与在索引时间发生的分析结果完全匹配术语输入。例如

// Indexing
input: ter@gmail.com -> standard analyzer -> ter,gmail.com in inverted index

// Querying
input: ter@gmail.com -> term query -> No exact matches for ter@gmail.com

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)
    );

有了此功能后,我们可以使用
过滤
查询通过
术语
过滤器搜索 完全匹配
****
****

// change dynamic to your type
var docs = client.Search<dynamic>(b => b
    .Query(q => q
        .Filtered(fq => fq
            .Filter(f => f
                .Term("fieldName", "ter@gmail.com")
            )
        )
    )
);

这将产生以下查询DSL

{
  "query": {
    "filtered": {
      "filter": {
        "term": {
          "fieldName": "ter@gmail.com"
        }
      }
    }
  }
}


 类似资料:
  • 我希望与字段中的字符串完全匹配,然后返回一天,提取所有此类记录。我所使用的json似乎也与简单的单词相匹配。我不确定我哪里出了问题。我需要向这个查询JSON添加吗?我目前拥有的JSON如下所示:

  • 我正在使用elasticsearch从json字段进行精确短语匹配。我尝试过多种语法,比如multi_match、query_string query_string我正在使用的语法; 我也尝试了过滤器而不是查询,但是过滤器在json上没有给出任何结果。我用于过滤器的语法是; 现在的问题是; 是否可以使用elasticsearch对json执行精确匹配操作?

  • 我目前正在Java应用程序上使用MongoDB的驱动程序。假设我将以下两个文档存储在一个集合中: 文件A: 文件B: 现在,我想通过使用key1和key2的值从集合中检索DocumentB的精确匹配,而不返回documenta,而不是_id,因为我事先不知道它。 如果我只是使用DocumentB作为查询(没有_id),Mongo也将返回DocumentA,因为它匹配所有的键和值,不考虑Docume

  • 问题内容: 我有以下表格(仅列出必需的属性) 药品(身份证,姓名), 通用(ID,名称), med_gen(med_id引用医学(id),gen_id引用一般(id),效力) 样本数据 药物 (1,“ Crocin”) (2,“ Stamlo”) (3,’NT Kuf’) 通用的 (1,“六氯丁啶”) (2,’苯甲酸甲酯’) med_gen (1,1,‘100mg’) (1、2,“ 50毫升”)

  • 本文向大家介绍MongoDB精确数组匹配,包括了MongoDB精确数组匹配的使用技巧和注意事项,需要的朋友参考一下 对于精确的数组匹配,只需在MongoDB中使用。让我们创建一个包含文档的集合- 在方法的帮助下显示集合中的所有文档- 这将产生以下输出- 这是对MongoDB数组匹配的查询- 这将产生以下输出-

  • 我正在尝试创建一个Lucene4.10索引。我只想在索引中保存我放入文档的确切字符串,witout标记化。 我在用StandardAnalyzer。 我试图搜索术语“燃料箱容量”@en(包括引号),所以我试图省略它们,并在术语周围添加了另外几个引号,以便让lucene理解我正在搜索整个文本。 如果我打印查询,我会得到:3:“燃料箱容量en”,但我不想拆分@符号上的文本。 我认为我的第一个问题是St