c# - 嵌套具有字段优先级的查询和过滤查询

标签 c# elasticsearch nest

我正在尝试使用Nest使用ElasticSearch构建搜索功能。我需要的是以下内容:

  • 我有商品表,我索引如下:
    foreach (var product in products) {
        Product product = new Product(product.ProductId, product.Name, product.Number, product.Description);   
        ElasticClient.Index(productes);
    }
    
  • 然后执行以下查询:
  • 这很好。我得到结果。
    var results = ElasticClient.Search<Product>(body => body.Query(query => query.QueryString(qs => qs.Query(key))).Size(20));
    

    以下两个查询都不起作用。为什么?我究竟做错了什么?
  • -
    var results = ElasticClient.Search<Product>(body => body.Filter(filter => filter.Term(x => x.Name, key)).Take(1000));
    
  • -
    var results = ElasticClient.Search<Product>(s => s
        .From(0)
        .Size(15)
        .Query(q => q
            .Term(p => p.Name, key)));
    
  • -
    var results = ElasticClient.Search<Product>(body => body.Query(query => query.ConstantScore(csq => csq.Filter(filter => filter.Term(x => x.Name, key.ToLower())))).Take(1000));
    

  • 我想首先了解为什么带过滤器的查询对我不起作用。最后,我想实现一个查询,该查询搜索给定的关键字并根据找到该字段的字段(列,属性)对结果进行优先级排序。

    因此,如果关键字位于“名称”字段中,则应在顶部将其返回。因此分别是“名称”,“编号”,“描述”。如何实现这样的查询?

    编辑:我尝试下面的查询,但它不返回任何内容。
    var results = ElasticClient.Search<Product>(body => body
        .Query(q => q
            .QueryString(qs => qs
                .OnFieldsWithBoost(d => d
                    .Add(entry => entry.Name, 5.0)
                    .Add(entry => entry.Number, 3.0)
                    .Add(entry => entry.Description, 2.0))
                .Query(key))));
    

    下面是一些样本数据;
    当我将“2000”作为关键字发送时,我得到以下查询结果1.查询,但其他查询将不返回任何结果。

    enter image description here

    最佳答案

    第一个查询返回结果而其他查询不返回结果的主要原因是,因为第一个查询是query_string,并且输入关键字(例如2000)将被分析并与您的任何字段(也将被分析)匹配。第二,第三和第四次查询不是这种情况,因为您使用的是term查询/过滤器,在该查询/过滤器中不分析输入,而是匹配

    如果我们使用第一个文档(id = 13),则会分析name字段并将其索引为以下标记:dr200012k(小写!),如以下命令所示:

    curl -XGET 'localhost:9200/_analyze?pretty&analyzer=standard' -d 'DR-2000 (12k)'
    
    {
      "tokens" : [ {
        "token" : "dr",
        "start_offset" : 0,
        "end_offset" : 2,
        "type" : "<ALPHANUM>",
        "position" : 1
      }, {
        "token" : "2000",
        "start_offset" : 3,
        "end_offset" : 7,
        "type" : "<NUM>",
        "position" : 2
      }, {
        "token" : "12k",
        "start_offset" : 9,
        "end_offset" : 12,
        "type" : "<ALPHANUM>",
        "position" : 3
      } ]
    }
    

    因此,在2000查询中搜索dr(或12kquery_string)时,您会找到该文档。搜索词2000不会产生任何结果,这在使用精确匹配的term查询/过滤器时是可以预期的。

    至于第二个关于提升字段的问题,查询什么都不返回的原因可能是因为字段名称为are lowercased by default(NEST的默认行为)。您应该确保使用小写的字段名称。

    更新

    如果您需要执行精确匹配,建议您使用analyzednot_analyzed字段将字段映射更改为multi-field string fields
    {
      "product" : {
        "properties" : {
          "name" : {
            "type" : "string",
            "index" : "analyzed",
            "fields" : {
              "raw" : {"type" : "string", "index" : "not_analyzed"}
            }
          }
        }
      }
    }
    

    然后,当您需要像行为这样的时,就可以使用name来查询query_string字段,而当您需要使用name.raw查询/过滤器进行完全匹配时,就可以使用term字段来查询。

    关于c# - 嵌套具有字段优先级的查询和过滤查询,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32313755/

    相关文章:

    elasticsearch - NEST编码问题?

    c# - 只获取几个结果集

    symfony - elasticsearch距离排序和计算不正确和不准确

    c# - 如何从pdf c#中获取具有特定颜色的文本#

    go - 如何为某种场景创建结构

    elasticsearch - ElasticSearch/Kibana:只读用户权限

    c# - 值列表中的值存在于弹性字段列表嵌套C#中

    c# - 使用 NEST 索引动态对象

    c# - 从异步方法更新进度条

    c# 静态类属性