使用字段优先级和筛选查询来嵌套查询

时间:2015-08-31 14:33:32

标签: 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);
    }
    
  • 然后我执行以下查询:

    1. 这很好用。我得到了结果。

      var results = ElasticClient.Search<Product>(body => body.Query(query => query.QueryString(qs => qs.Query(key))).Size(20));
      

      以下查询都不起作用。为什么?我做错了什么?

    2. -

      var results = ElasticClient.Search<Product>(body => body.Filter(filter => filter.Term(x => x.Name, key)).Take(1000));
      
    3. -

      var results = ElasticClient.Search<Product>(s => s
          .From(0)
          .Size(15)
          .Query(q => q
              .Term(p => p.Name, key)));
      
    4. -

      var results = ElasticClient.Search<Product>(body => body.Query(query => query.ConstantScore(csq => csq.Filter(filter => filter.Term(x => x.Name, key.ToLower())))).Take(1000));
      

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

因此,如果关键字位于&#34;名称&#34;字段,它应该返回顶部。分别是&#34;姓名&#34;,&#34;号码&#34;,&#34;说明&#34;。我怎样才能实现这样的查询?

编辑:我尝试了下面的查询,但它没有返回任何内容。

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

以下一些样本数据; 当我发送&#34; 2000&#34;作为关键字,我得到以下结果1.查询但其他人不会返回任何内容。

enter image description here

1 个答案:

答案 0 :(得分:1)

第一个查询返回结果而其他查询不返回结果的主要原因是第一个查询是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字段;当您需要与{{1完全匹配的行为时,name.raw字段查询/过滤。