Jaro elastické : Co je správný způsob, jak používat vnořené pole?

0

Otázka

Jsem docela nový ElasticSearch. Pracuji na projektu, kde musíme hledat pro objekt (Nabídka), která obsahuje Sadu dvou (OfferTranslation). Cílem je, aby výzkum založený na některé z Nabídky oborů, ale také hodně OfferTranslation pole. Zde je minified verze obou tříd :

Offer.class (všimněte si, že jsem komentovaný soubor s @Pole(type= FieldType.Vnořené), tak i Vnořené dotazy, jak zmíněna v oficiální 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;
}

Očekávané chování by bylo, že můžu udělat nestedQueries jako tak :

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

Ale to, co jsem si je výjimka : nepodařilo se vytvořit dotaz: [nested] vnořený objekt pod cestu [offersTranslations] není vnořených typ"

EDIT : můžu přístup offersTranslations.jazyk.kód pomocí běžné dotazy (což mi nevadí v současné době). Ale já pořád nerozumím.

Můj mapování říká, oblasti offersTranslations není vnořený typ, jak můžete vidět výše, ale jelikož jsem použil @Pole(type = FieldType.Vnořené) nemám opravdu pochopit, že chování. Mohl by někdo vysvětlit?

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

Nejlepší odpověď

1

Jak byl index mapování vytvořil? To nevypadá jako na Jaře Dat Elasticsearch napsal toto mapování. Vnořený typ offerTranslations chybí jak jste viděli a textových polí mají .keyword podpole. To vypadá, jako by data byla vložena do indexu bez nutnosti mapování definované a tak Elasticsearch udělal automatické mapování. V tomto případě, hodnoty @Field popisy nejsou používány.

Musíte mít na Jaře Dat Elasticsearch vytvořit index s mapováním. To se stane automaticky, pokud index neexistuje a používáte Spring Data Elasticsearch repozitáře, nebo budete muset použít IndexOperations.createWithMapping funkce v aplikaci.

Další věc, kterou jsem si všiml: zdá se, že používáte stejné třídy entity pro různé Jarní Datových skladů, míchání silně popisy. Měli byste používat různé subjekty na různých obchodech.

2021-11-22 17:12:04

Zkoušel jsem mazání mapování pomocí kibana : ODSTRAŇTE nabídka/_mapping a novou indexaci moje nabídky. Ale možná pomocí explicitní "createWithMapping" by mohlo fungovat lépe, dám vám vědět, jestli to pomůže ! Každopádně děkuji
Aymane EL Jahrani

Ahoj, tak jsem se snažil pomocí createWithMapping, ale to se nezdá být jednoduché. Můžete potvrdit, že tohle je ten správný způsob, jak používat to ? github.com/spring-projects/spring-data-elasticsearch/blob/main/...
Aymane EL Jahrani
0

KROKY K ŘEŠENÍ :

  • Použití Kibana, aby ujistěte se, že jste ODSTRANIT <index_name>/_mapping
  • Podívej se do své entity třídy pro objekty, které potřebujete, které by mohly být v @JsonIgnoreProperties
  • Ujistěte se, že jste DYCHTIVĚ nahrát váš toMany vztah atributy (jinak elastický nebude-li vytvořit mapování na data, která jste nikdy nedal)
  • Z této zkušenosti bych řekl, že vyhnout se používání Vnořených polí, nemohl jsem vidět žádné výhody z jejich použití. Tak se podívejte, jestli to je pro vás taky !
2021-11-25 23:17:34

Na jaře Dat Elasticsearch dos nic dělat s @JsonIgnoreProperties anotace. Elasticsearch je ne relační databáze a nemá ani ponětí o vztazích mezi entitami.
P.J.Meisch

To je pravda, ale na jaře se, že když serialising data. To je, jak jsem se dostat mé bytosti ...
Aymane EL Jahrani

Jaro samo o sobě nemá dělat, že. Spring Data JPA, to například. Na jaře Dat Elasticsearch nedělá to. Jedná se o různé Jarní Datových modulů.
P.J.Meisch

Knihovna fasterxml.jackson dělá ,a funguje to pomocí anotací JPA/Hibernate entity. To je to co jsem v tomto projektu jak můžete vidět v mém kódu...
Aymane EL Jahrani

V jiných jazycích

Tato stránka je v jiných jazycích

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