Molla elastica : che Cosa è il modo corretto di utilizzare i campi nidificati?

0

Domanda

Sono abbastanza nuovo di ElasticSearch. Sto lavorando su un progetto in cui abbiamo bisogno di cercare un oggetto (Offerta) che contiene un Set di due (OfferTranslation). L'obiettivo è quello di effettuare una ricerca in base ad alcuni campi Offrono, ma anche un sacco di OfferTranslation campi. Ecco una versione minified di entrambe le classi :

Offer.class (nota che ho annotato con @Campo(tipo= Tipocampo.Nidificato) così posso fare le query Nidificate, come indicato nella gazzetta ufficiale doc) :

@org.springframework.data.elasticsearch.annotations.Document(indexName = "offer")
@DynamicMapping(DynamicMappingValue.False)
public class Offer implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    @Field(type = FieldType.Long)
    private Long id;

    @OneToMany(mappedBy = "offer", targetEntity = OfferTranslation.class, cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
    @JsonIgnoreProperties(
        value = { "pictures", "videos", "owner", "contexts", "offer", "personOfInterests", "followers" },
        allowSetters = true
    )
    @Field(type = FieldType.Nested, store = true)
    private Set<OfferTranslation> offersTranslations = new HashSet<>();


}

OfferTranslation.class :

@DynamicMapping(DynamicMappingValue.False)
public class OfferTranslation implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    @Field(type = FieldType.Long)
    private Long id;

    @NotNull
    @Size(max = 100)
    @Column(name = "title", length = 100, nullable = false)
    @Field(type = FieldType.Text)
    private String title;

    @NotNull
    @Size(max = 2000)
    @Column(name = "summary", length = 2000, nullable = false)
    @Field(type = FieldType.Text)
    private String summary;

    @Size(max = 2000)
    @Column(name = "competitor_context", length = 2000)
    @Field(type = FieldType.Text)
    private String competitorContext;

    @NotNull
    @Size(max = 2000)
    @Column(name = "description", length = 2000, nullable = false)
    @Field(type = FieldType.Text)
    private String description;

    @NotNull
    @Enumerated(EnumType.STRING)
    @Column(name = "maturity", nullable = false)
    @Field(type = FieldType.Auto)
    private RefMaturity maturity;

    @ManyToOne
    @Field(type = FieldType.Object, store = true)
    private RefLanguage language;

    @NotNull
    @Column(name = "created_at", nullable = false)
    @Field(type = FieldType.Date)
    private Instant createdAt;
}

Il comportamento previsto è che posso fare nestedQueries così :

QueryBuilder qBuilder = nestedQuery("offersTranslations",boolQuery().must(termQuery("offersTranslations.language.code",language)), ScoreMode.None);

Ma quello che ottengo è un'eccezione : impossibile creare la query: [nidificati] oggetto nidificato sotto il percorso [offersTranslations] non è di tipo annidato"

EDIT : posso accedere offersTranslations.lingua.codice utilizzando le normali query (che in realtà non mi preoccupa, al momento). Ma non riesco ancora a capire.

La mia mappatura dice il campo offersTranslations non è di un tipo annidato come si può vedere sopra, ma dal momento che ho usato @Campo(tipo = Tipocampo.Nidificato) io non capisco questo comportamento. Qualcuno potrebbe spiegare?

{
  "offer" : {
    "mappings" : {
      "properties" : {
        "_class" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "categories" : {
          "properties" : {
            "id" : {
              "type" : "long"
            }
          }
        },
        "criteria" : {
          "properties" : {
            "id" : {
              "type" : "long"
            }
          }
        },
        "id" : {
          "type" : "long"
        },
        "keywords" : {
          "properties" : {
            "id" : {
              "type" : "long"
            }
          }
        },
        "offersTranslations" : {
          "properties" : {
            "competitorContext" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "createdAt" : {
              "type" : "date"
            },
            "description" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "id" : {
              "type" : "long"
            },
            "language" : {
              "properties" : {
                "code" : {
                  "type" : "text",
                  "fields" : {
                    "keyword" : {
                      "type" : "keyword",
                      "ignore_above" : 256
                    }
                  }
                },
                "id" : {
                  "type" : "long"
                },
                "name" : {
                  "type" : "text",
                  "fields" : {
                    "keyword" : {
                      "type" : "keyword",
                      "ignore_above" : 256
                    }
                  }
                }
              }
            },
            "maturity" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "state" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "summary" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "title" : {
              "type" : "text",
              "fields" : {
                "keyword" : {
                  "type" : "keyword",
                  "ignore_above" : 256
                }
              }
            },
            "updatedAt" : {
              "type" : "date"
            }
          }
        },
        "units" : {
          "properties" : {
            "id" : {
              "type" : "long"
            }
          }
        }
      }
    }
  }
}
2

Migliore risposta

1

Come è stato l'indice di mappatura creata? Non assomiglia a Molla Dati di Elasticsearch ha scritto questa mappatura. Nidificato tipo di offerTranslations manca, come si è visto e i campi di testo sono un .keyword sottocampo. Questo appare come l'inserimento dei dati nell'indice, senza avere una mappatura definita e così Elasticsearch fatto una mappatura automatica. In questo caso, i valori di @Field le annotazioni non sono utilizzati.

È necessario disporre di Dati della Molla Elasticsearch creare l'indice con la mappatura. Questo avviene automaticamente se l'indice non esiste e si sta utilizzando Dati della Molla Elasticsearch repository, o è necessario utilizzare il IndexOperations.createWithMapping funzione dell'applicazione.

Un'altra cosa che ho notato: sembra che tu stia utilizzando la stessa classe di entità per diversi Primavera archivi di Dati, di miscelazione pesantemente le annotazioni. Si dovrebbe utilizzare diversi enti per diversi punti vendita.

2021-11-22 17:12:04

Ho provato a cancellare l'associazione utilizzando kibana : ELIMINARE offerta/_mapping e reindexing le mie offerte. Ma forse utilizzando un esplicito "createWithMapping" potrebbe funzionare meglio, ti farò sapere se questo aiuta ! Grazie comunque
Aymane EL Jahrani

Ciao, quindi ho provato ad usare il createWithMapping, ma non sembra essere molto semplice. Potete confermare che questo è il modo corretto di usarlo ? github.com/spring-projects/spring-data-elasticsearch/blob/main/...
Aymane EL Jahrani
0

LA PROCEDURA PER RISOLVERE :

  • Utilizzare Kibana per assicurarsi che si ELIMINA <index_name>/_mapping
  • Guarda nel tuo classi di entità per gli oggetti che potrebbero essere in un @JsonIgnoreProperties
  • Assicurarsi di caricare con impazienza il tuo toMany rapporto attributi (altrimenti elastico non creare un mapping dei dati non avete mai dato)
  • Da questa piccola esperienza, direi di evitare di utilizzare i campi Nidificati, io non riuscivo a vedere alcun vantaggio del loro utilizzo. Quindi verificare se questo è il caso per voi !
2021-11-25 23:17:34

Dati della molla Elasticsearch dos e non fare nulla con il @JsonIgnoreProperties annotazione. Elasticsearch non è di database relazionali e non ha alcuna nozione di relazioni tra entità.
P.J.Meisch

Questo è vero, ma la primavera fa che quando serialising dati. Come posso ottenere il mio enti ...
Aymane EL Jahrani

La primavera non fa che. Molla i Dati dell'APP che fa per esempio. Dati della molla Elasticsearch non farlo. Questi sono diversi Primavera moduli di Dati.
P.J.Meisch

La biblioteca fasterxml.jackson fa ,e funziona con le annotazioni sul JPA/Hibernate. Che è quello che uso io in questo progetto, come si può vedere nel mio codice...
Aymane EL Jahrani

In altre lingue

Questa pagina è in altre lingue

Русский
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................