我怎样才能保留我的距离表示得分字段并将其映射到我的结果实体中?

How can I keep my, distance representing, score field and map it into my resulting entity?

我正在使用以下查询:

NativeSearchQuery nsq = new NativeSearchQueryBuilder()
    .withQuery(qb)
    .withPageable(PageRequest.of(page, PAGE_SIZE))
    .withSort(sb)
    .build();

使用以下 SortBuilder:

SortBuilders.geoDistanceSort("customer.address.geoLocation",
         customer.getAddress().getGeoLocation().toGeoPoint())
    .order(SortOrder.ASC)
    .unit(DistanceUnit.KILOMETERS);

正在生成所需的排序查询:

"sort": [
  {
    "_geo_distance" : {
      "customer.address.geoLocation" : [
        {
          "lat" : 40.4221663,
          "lon" : -3.7148336
        }
      ],
      "unit" : "km",
      "distance_type" : "arc",
      "order" : "asc",
      "validation_method" : "STRICT",
      "ignore_unmapped" : false
    }
  }
]

此外,每个生成的文档都返回以公里为单位的参考参数的距离:

"sort": [2.4670609224864997]

我需要这个值作为我的域的一部分,但我无法将它推入我的对象。我尝试了一种简单的方法,将它定义到我的域中,因为它似乎是 float[] 但我一直得到 null。我正在使用 Jackson 进行(反)序列化。

  private float[] sort;

  public float[] getSort() {
    return this.sort;
  }

  public void setSort(float[] score) {
    this.sort = score;
  }

我的存储库:

  public interface ElasticsearchProductRepository 
        extends ElasticsearchRepository<Product, String> {
    Page<Product> search(SearchQuery searchQuery);
  }

产品:

@Entity
@Table(name = "product")
@Document(indexName = "product", createIndex = true, type = "_doc")
@Setting(settingPath = "elasticsearch/product-index.json")
@DynamicTemplates(mappingPath = "elasticsearch/product-dynamic-templates.json")
public class Product {

...

  @org.springframework.data.annotation.Id
  @javax.persistence.Id
  @GeneratedValue(strategy = GenerationType.AUTO)
  @JsonView(ResponseView.class)
  private long id;

  @Field(analyzer = "autocomplete", type = FieldType.Text, searchAnalyzer="standard")
  @JsonView(CreationRequestView.class)
  private String productName;
  private float[] sort;

...

  public float[] getSort() {
    return this.sort;
  }

  public void setSort(float[] score) {
    this.sort = score;
  }

}

我添加了以下脚本字段:

  "script_fields": {
    "distance": {
      "script": {
        "lang":   "painless",
        "source": "doc['sort']",
        "params": {
        }
      }
    }

}

但是找不到排序字段。

"reason": "No field found for [sort] in mapping with types []"

实际上 doc 似乎引用了 doc._source...我如何从 Elastic 脚本中引用这么大的数据?

目前在 Spring Data Elasticsearch 中,returned 实体是从 _source 字段中的 returned 值填充的。 returned sort 不是其中的一部分,而是每个搜索命中的附加信息 return 的一部分。

对于下一个版本 (4.0),我们目前正在重写 returned 命中的处理方式。下一个版本将有一个 SearchHit<T> class,其中 T 是实体域 class,并且 SearchHit 对象包含此实体以及其他信息,如分数,突出显示、脚本字段、排序等

计划存储库方法可以 return 这些 SearchHit 对象的列表或页面。

但目前,来自查询的排序将导致排序 return,但您无法检索排序值本身 - 在您的情况下这很糟糕,因为它们是动态计算的。

编辑:

您可以通过在实体中为 geo_distance 定义 属性 并使用 @ScriptedField 注释对其进行注释来检索该值,然后在您的本机查询中提供脚本。示例可以在 tests for Spring Data Elasticsearch 中找到。此示例适用于 ElaticsearchTemplate,但将此查询传递到存储库搜索方法应该没有区别。

编辑 25.12.2019:

当前的 master 分支,将成为 Spring Data Elasticsearch 4.0,实现了这一点。找到的文档在 SearchHit 对象中 returned,该对象还包含 sortValues.