NEST 7.6.2使用FieldValueFactorFunction输出无效查询JSON的问题
问题根因判断
- 你写的初始化语法完全符合NEST 7.6.2的API定义,不存在写法错误
- 出现JSON结构错位、重复嵌套的问题,是NEST 7.6.2版本本身的序列化映射设计缺陷:该版本的
FieldValueFactorFunction类,重复定义了本该属于通用ScoreFunction基类的Filter、Weight属性,序列化时会把这两个属性同时输出到两个层级——既在ScoreFunction的外层正确位置生成,又错误地塞进内部field_value_factor块下,最终生成不符合ES DSL规范的冗余结构。ES解析时因为field_value_factor块不允许存在这两个属性,就会抛出和实际字段名不完全对应的解析报错。
可正常落地的替代实现
1. Fluent描述符写法(推荐)
不要直接手动实例化FieldValueFactorFunction对象,走函数得分查询的内置描述符链路,绕开有问题的类序列化逻辑:
.FunctionScore(fs => fs .Functions(scoreFuncs => scoreFuncs .FieldValueFactor(fvf => fvf .Field("foo") .Modifier(FieldValueFactorModifier.Log1P) .Missing(1) ) .Weight(0.2) .Filter(filter => filter.Match(m => m .Field("bar") .Query("1") )) ) )
这种写法最终生成的JSON结构完全匹配ES官方要求,不会出现重复嵌套的冗余字段。
2. 对象初始化器适配写法
如果习惯对象初始化器的编码风格,只要把原本写在FieldValueFactorFunction内部的Filter和Weight挪到外层的通用ScoreFunction对象上,仅把field_value_factor本身支持的专属属性留在内部对象里即可:
new ScoreFunction { // 仅保留field_value_factor 自身支持的属性 FieldValueFactor = new FieldValueFactorFunction { Field = "foo", Modifier = FieldValueFactorModifier.Log1P, Missing = 1 }, // 函数通用属性放到外层ScoreFunction层级 Filter = new MatchQuery { Field = "bar", Query = "1" }, Weight = .2 }
补充版本说明
- 这个重复序列化的问题在NEST后续的7.x小版本迭代中已经被修复,升级到7.17及以上版本后,直接在
FieldValueFactorFunction上声明Filter和Weight也能生成正确的结构。但在7.6.2版本下,不需要强行调整ES配置去适配错误生成的JSON,用上面的写法即可正常运行。
内容的提问来源于stack exchange,提问作者Rob
相关产品推荐
相关产品推荐

