Nest将范围边界作为字符串而不是双倍 [英] Nest renders range boundaries as string instead of double

查看:104
本文介绍了Nest将范围边界作为字符串而不是双倍的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

  var isTerms = new List&FunC< QueryDescriptor< ElasticCheckIn> ,Nest.QueryContainer>>(); 

var dmaxPrice = maxPrice.HasValue? (double?)maxPrice.Value:100000d;
var dminPrice = minPrice.HasValue? (double?)minPrice.Value:0d;
mustTerms.Add(mt => mt.Range(rd => rd.OnField(price)。LowerOrEquals(dmaxPrice).GreaterOrEquals(dminPrice)));

Func< QueryDescriptor&ElasticCheckIn>,Nest.QueryContainer> queryFunc = qd => qd
.FunctionScore(fsq => fsq
.Query(fsqd => fsqd
.Bool(bqd => bqd
.Must(mustTerms.ToArray())
.Should(shouldTerms.ToArray())))
.Functions(fsd => fsd
.Linear(createDate,fsdfd => fsdfd
.Scale 1d)
.Decay(0.5d)
.Origin(DateTime.UtcNow.ToString(O)))));

Func< SearchDescriptor< ElasticCheckIn>,SearchDescriptor&ElasticCheckIn>> searchFunc = q => q
.Index(_indexName)
.Type(_typeName)
.Query(queryFunc)
.Size(limit);

此代码生成查询:

query:{
function_score:{
functions:[
{
linear
createDate:{
origin:2015-03-16T12:48:14.2660667Z,
scale:1d,
decay 0.5
}
}
}
],
查询:{
bool:{
必须:[
{
range:{
price:{
gte:29.97,
lte:67.5
}
}
}
]
}
}
}
}
}

如您所见,Nest将范围部分中的双重值作为字符串:

  {
range:{
price:{
gte:29.9 7,
lte:67.5
}
}
}

这导致:


NumberFormatException [对于输入字符串:29.97]


当我手动更正双重值时,弹性搜索正确返回查询结果。如何让Nest正确显示双重值?



更新:



此索引的映射:

  {
myindice:{
mappings:{
mytype:{
properties:{
createDate:{
type:date,
format:dateOptionalTime
},
id:{
type:string
},
/ *其他字段* /
price
type:long
}
/ *其他字段* /
}
}
}
}
}

我们没有明确地映射价格字段。文档中的某些价格字段是整数,有两倍。

解决方案

这可能是NEST中的一个错误,使用语法您已选择,您可以在 github repo 中创建新问题。更标准的语法是创建一个C#POCO来表示您的ES数据。如下所示:

  [ElasticType] 
public class Type1
{
public string Id {get;组; }
public DateTime CreationDate {get;组; }
public double价格{get;组; }
}

因此,您的查询语法变得更加简单:

  var result2 = ElasticClient.Search< Type1>(s => s 
.Query(q => q
.Filtered(f => f
.Filter(ff => ff
.Range(r => r
.OnField(rf => rf.Price)
.GreaterOrEquals(29.97)
.LowerOrEquals(67.5)




);


I am querying ElasticSearch with Nest, with this code:

var mustTerms = new List<Func<QueryDescriptor<ElasticCheckIn>, Nest.QueryContainer>>();

var dmaxPrice = maxPrice.HasValue ? (double?)maxPrice.Value : 100000d;
var dminPrice = minPrice.HasValue ? (double?)minPrice.Value : 0d;
mustTerms.Add(mt => mt.Range(rd => rd.OnField("price").LowerOrEquals(dmaxPrice).GreaterOrEquals(dminPrice)));

Func<QueryDescriptor<ElasticCheckIn>, Nest.QueryContainer> queryFunc = qd => qd
    .FunctionScore(fsq => fsq
         .Query(fsqd => fsqd
             .Bool(bqd => bqd
                 .Must(mustTerms.ToArray())
                 .Should(shouldTerms.ToArray())))
                 .Functions(fsd => fsd
                     .Linear("createDate", fsdfd => fsdfd
                         .Scale("1d")
                         .Decay(0.5d)
                         .Origin(DateTime.UtcNow.ToString("O")))));

Func<SearchDescriptor<ElasticCheckIn>, SearchDescriptor<ElasticCheckIn>> searchFunc = q => q
    .Index(_indexName)
    .Type(_typeName)
    .Query(queryFunc)
    .Size(limit);

This code produces query:

{
  "query": {
    "function_score": {
      "functions": [
        {
          "linear": {
            "createDate": {
              "origin": "2015-03-16T12:48:14.2660667Z",
              "scale": "1d",
              "decay": 0.5
            }
          }
        }
      ],
      "query": {
        "bool": {
          "must": [
            {
              "range": {
                "price": {
                  "gte": "29.97",
                  "lte": "67.5"
                }
              }
            }
          ]
        }
      }
    }
  }
}

As you see, Nest renders the double values in the range part as strings:

{
    "range": {
        "price": {
            "gte": "29.97",
            "lte": "67.5"
        }
    }
}

This results in:

NumberFormatException[For input string: "29.97"]

When I correct the double values by hand, elasticsearch correctly return the query results. How can I get Nest to render the double values correctly?

Update:

Mapping for this index:

{
  "myindice": {
    "mappings": {
      "mytype": {
        "properties": {
          "createDate": {
            "type": "date",
            "format": "dateOptionalTime"
          },
          "id": {
            "type": "string"
          },
          /* other fields */
          "price": {
            "type": "long"
          }
          /* other fields */
        }
      }
    }
  }
}

We did not map the price field as long specifically. Some of the price fields on the docs are integers, some doubles.

解决方案

This may be a bug in NEST using the syntax that you've choosen, you could create a new issue in their github repo. A more standard syntax would be to create a C# POCO to represent your ES data. something like this:

[ElasticType]
public class Type1
{
    public string Id { get; set; }
    public DateTime CreationDate { get; set; }
    public double Price { get; set; }
}

With that, your query syntax become much, much simpler:

         var result2 = ElasticClient.Search<Type1>(s=>s
             .Query(q=> q
                .Filtered(f=>f
                    .Filter(ff=> ff
                        .Range(r=>r
                            .OnField(rf=>rf.Price)
                            .GreaterOrEquals(29.97)
                            .LowerOrEquals(67.5)
                        )
                    )
                )
             )
        );

这篇关于Nest将范围边界作为字符串而不是双倍的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆