Primăvara elastic : care este modul corect de a folosi câmpurile imbricate?

0

Problema

Sunt destul de nou pentru ElasticSearch. Lucrez la un proiect în care am nevoie pentru a căuta un obiect (Oferta) care conține un Set de două (OfferTranslation). Scopul este de a face cercetare bazate pe unele dintre Oferta de domenii, dar, de asemenea, o mulțime de OfferTranslation domenii. Aici e o versiune minified de ambele clase :

Offer.class (rețineți că am adnotate cu @Domeniu(tip= FieldType.Imbricate) deci, eu pot face interogări Imbricate, ca mentionate în monitorul oficial 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;
}

Comportamentul așteptat ar fi ca pot face nestedQueries fi deci :

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

Dar ceea ce primesc este o excepție : nu a reușit să creeze interogare: [imbricate] imbricate obiect în calea [offersTranslations] nu este de tip imbricate"

EDIT : nu pot accesa offersTranslations.limba.cod folosind normal interogări (care de fapt nu mă deranjează în acest moment). Dar eu încă nu înțeleg cu adevărat.

Mi cartografiere spune domeniu offersTranslations nu este de un tip imbricate după cum puteți vedea mai sus, dar de cand am folosit @Domeniu(tip = FieldType.Imbricate) nu prea inteleg acest comportament. Ar putea cineva explica?

{
  "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

Cel mai bun răspuns

1

Cum a fost indicele de cartografiere a creat? Nu arata ca Primavara Date Elasticsearch scris această cartografiere. Imbricate tip de offerTranslations lipsește, după cum ați văzut și câmpuri de text au o .keyword subdomeniu. Acest lucru se pare ca datele au fost introduse în indicele fără a avea o cartografiere definite și deci Elasticsearch făcut o cartografiere automată. În acest caz, valorile @Field adnotări nu sunt utilizate.

Trebuie să aveți Primăvară Date Elasticsearch crea index cu cartografiere. Acest lucru se va întâmpla în mod automat în cazul în care indicele nu există și utilizați Primăvară Date Elasticsearch magazii, sau aveți nevoie pentru a utiliza IndexOperations.createWithMapping funcția în cererea dumneavoastră.

Un alt lucru am observat: se pare că sunteți folosind aceeași clasă de entități pentru Primăvara diferite magazine de Date, amestec puternic de adnotări. Ar trebui să utilizați diferite entități pentru diferite magazine.

2021-11-22 17:12:04

Am încercat ștergerea de cartografiere folosind kibana : ȘTERGEȚI oferta/_mapping și reindexarea ofertele mele. Dar poate folosind un explicite "createWithMapping" s-ar putea să funcționeze mai bine, o să te anunț dacă acest lucru vă ajută ! Multumesc oricum
Aymane EL Jahrani

Buna ziua, așa că am încercat, folosind createWithMapping, dar nu pare a fi simplă. Puteți confirma că acesta este modul corect de a folosi aceasta ? github.com/spring-projects/spring-data-elasticsearch/blob/main/...
Aymane EL Jahrani
0

PAȘI PENTRU A REZOLVA :

  • Utilizarea Kibana să asigurați-vă că ȘTERGEȚI <index_name>/_mapping
  • Uită-te în clase entitate pentru obiectele de care ai nevoie care ar putea fi într-un @JsonIgnoreProperties
  • Asigurați-vă că cu NERĂBDARE încărcați toMany relație atributele (altfel elastic nu va crea o mapare pentru un date nu i-ai dat)
  • De la această experiență, aș spune evita folosind câmpurile Imbricate, nu am putut vedea nici un avantaj din utilizarea lor. Deci, a verifica dacă acesta este cazul pentru tine !
2021-11-25 23:17:34

Primăvara Date Elasticsearch dos nu face nimic cu @JsonIgnoreProperties adnotare. Elasticsearch este nici o bază de date relațională și nu are noțiunea de relații între entități.
P.J.Meisch

E adevărat, dar primăvara asta, când l serialising de date. Așa-mi iau entități ...
Aymane EL Jahrani

Primăvara, în sine, nu face asta. Primăvara Date APP face că, de exemplu. Primăvara Date Elasticsearch nu o face. Acestea sunt diferite de Primăvară modulele de Date.
P.J.Meisch

Biblioteca fasterxml.jackson face asta ,și funcționează utilizând adnotări pe JPA/Hibernate entități. Asta e ceea ce am folosit în acest proiect, după cum puteți vedea în codul meu...
Aymane EL Jahrani

În alte limbi

Această pagină este în alte limbi

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