Home > Enterprise >  How to sort by nested field which has multi-field defined
How to sort by nested field which has multi-field defined

Time:11-30

first of all, this is my very first post on here, so bear with me

I am trying to find a proper way to sort on an elasticsearch nested field in a class which is defined as follows:

public class SignalementConflitRechercheAvanceeDocument extends SignalementConflitNestedRechercheAvanceeDocument{

private static final long serialVersionUID = 1L;

// Objet(s) de croisement
@Field(type = FieldType.Nested)
private EtablissementNestedRechercheAvanceeDocument etablissementRechercheAvanceeDocument;

}

This nested object is defined as follows:

public class EtablissementNestedRechercheAvanceeDocument implements Serializable {
    /**
     *
     */
    protected static final long serialVersionUID = 1L;

    @Id
    @MultiField(mainField = @Field(type = FieldType.Text, analyzer = "index-analyzer", searchAnalyzer = "search-analyzer"), otherFields = {
            @InnerField(suffix = "tri", type = FieldType.Keyword, normalizer = "sort-normalizer") })
    protected String siret;

    @Field(type = FieldType.Boolean)
    protected boolean secteur;

    @Field(type = FieldType.Keyword)
    protected String siren;

    @Field(type = FieldType.Long)
    protected Long regId;

    @MultiField(mainField = @Field(type = FieldType.Text), otherFields = {
            @InnerField(suffix = "tri", type = FieldType.Keyword) })
    protected String libelleRegion;

}

Or

"regId": {
    "type": "long"
},
"secteur": {
    "type": "boolean"
},
"siren": {
    "type": "keyword"
},
"siret": {
    "type": "text",
    "fields": {
        "tri": {
            "type": "keyword",
            "normalizer": "sort-normalizer"
        }
    },
    "analyzer": "index-analyzer",
    "search_analyzer": "search-analyzer"
},
"libelleService": {
    "type": "text",
    "fields": {
        "tri": {
            "type": "keyword"
        }
    }
},

in pure elastic syntax.

I have already tried many combinations, but what should be the closest to a clean request is

{
    "query": {
        "bool": {
            "must": [
                {
                    "nested": {
                        "query": {
                            "bool": {
                                "must": [
                                    {
                                        "bool": {
                                            "should": [
                                                {
                                                    "match": {
                                                        "etablissementRechercheAvanceeDocument.secteur": {
                                                            "query": "false",
                                                            "operator": "OR",
                                                            "prefix_length": 0,
                                                            "max_expansions": 50,
                                                            "fuzzy_transpositions": true,
                                                            "lenient": false,
                                                            "zero_terms_query": "NONE",
                                                            "auto_generate_synonyms_phrase_query": true,
                                                            "boost": 1
                                                        }
                                                    }
                                                }
                                            ],
                                            "adjust_pure_negative": true,
                                            "boost": 1
                                        }
                                    }
                                ],
                                "adjust_pure_negative": true,
                                "boost": 1
                            }
                        },
                        "path": "etablissementRechercheAvanceeDocument",
                        "ignore_unmapped": false,
                        "score_mode": "max",
                        "boost": 1,
                        "inner_hits": {
                            "ignore_unmapped": false,
                            "from": 0,
                            "size": 100,
                            "version": false,
                            "seq_no_primary_term": false,
                            "explain": false,
                            "track_scores": false
                        }
                    }
                }
            ],
            "adjust_pure_negative": true,
            "boost": 1
        }
    },
    "sort": [
        {
            "etablissementRechercheAvanceeDocument.siret.tri": {
                "order": "asc",
                "nested":{
                  "path": "etablissementRechercheAvanceeDocument.siret",
                }
            }
        }
    ]
}

In all cases I receive the same 400 error stack

Error 400.
{"error":{"root_cause":[{"type":"query_shard_exception","reason":"[nested] failed to find nested object under path [etablissementRechercheAvanceeDocument.siret]","index_uuid":"lGwiXFs4RDCIZ6jqGVzPYQ","index":"signalement-conflit-recherche-avancee-doc"}],"type":"search_phase_execution_exception","reason":"all shards failed","phase":"query","grouped":true,"failed_shards":[{"shard":0,"index":"signalement-conflit-recherche-avancee-doc","node":"WKtmnvO8SdOBplHuGeLxIw","reason":{"type":"query_shard_exception","reason":"[nested] failed to find nested object under path [etablissementRechercheAvanceeDocument.siret]","index_uuid":"lGwiXFs4RDCIZ6jqGVzPYQ","index":"signalement-conflit-recherche-avancee-doc"}}]},"status":400}

And for the love of me I can't find what I am missing here. Any help is appreciated

CodePudding user response:

The query you were trying just had a little error, in "path" you must set the parent nested field:

POST test_nest/_search
{
  "sort": [
    {
      "etablissementRechercheAvanceeDocument.siret.tri": {
        "order": "asc",
        "nested": {
          "path": "etablissementRechercheAvanceeDocument"
        }
      }
    }
  ]
}

More about nested fields

To run nested queries your field must be of type Nested:

https://www.elastic.co/guide/en/elasticsearch/reference/current/nested.html

Nested sort:

https://www.elastic.co/guide/en/elasticsearch/reference/current/sort-search-results.html#nested-sorting

I wrote an article about the differences between nested field types and objects here:

https://opster.com/guides/elasticsearch/data-architecture/elasticsearch-nested-field-object-field/

In short, nested field type preserve the relation between the nested document properties, object flats it all.

With Nested fields you can do things like:

Document with child.color = red AND child.size = large within the same children

Without nested type you can only do child.color = red AND child.size = large across all that document children

  • Related