Spring elastic: İç içe geçmiş alanları kullanmanın doğru yolu nedir?

0

Soru

Elasticsearch'te oldukça yeniyim. İki (OfferTranslation) Kümesi içeren bir nesneyi (Teklif) aramamız gereken bir proje üzerinde çalışıyorum. Amaç, bazı Teklif alanlarına değil, aynı zamanda birçok teklif çeviri alanına dayalı araştırma yapmaktır. İşte her iki sınıfın da küçültülmüş bir versiyonu :

Teklif.sınıf(Kümeye @Field (type= FieldType) ile açıklama eklediğimi unutmayın.İç içe geçmiş) böylece resmi belgede belirtildiği gibi iç içe geçmiş sorgular yapabilirim) :

@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<>();


}

Çeviri öneriyorum.sınıf :

@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;
}

Beklenen davranış, nestedqueries'i şu şekilde yapabilirim :

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

Ancak aldığım şey bir istisnadır: sorgu oluşturulamadı: [offersTranslations] yolu altındaki [nested] iç içe geçmiş nesne iç içe geçmiş türde değil"

DÜZENLEME: Teklif çevirilerine erişebilirim.dil.normal sorguları kullanan kod(şu anda beni gerçekten rahatsız etmiyor). Ama hala gerçekten anlamıyorum.

Eşlemem, alan tekliflerinin yukarıda gördüğünüz gibi iç içe geçmiş bir türde olmadığını, ancak @Field(type = FieldType) kullandığımdan beri olduğunu söylüyor.Bu davranışı gerçekten anlamıyorum. Olabilir biri açıklayabilir?

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

En iyi cevabı

1

Dizin eşlemesi nasıl oluşturuldu? Spring Data Elasticsearch bu eşlemeyi yazmış gibi görünmüyor. İç içe geçmiş türü offerTranslations gördüğünüz gibi eksik ve metin alanları bir .keyword alt alan. Bu, tanımlanmış bir eşlemeye sahip olmadan dizine veri eklenmiş gibi görünüyor ve bu nedenle Elasticsearch otomatik bir eşleme yaptı. Bu durumda, değerleri @Field ek açıklamalar kullanılmaz.

Spring Data Elasticsearch'ün eşleme ile dizin oluşturmasını sağlamanız gerekir. Dizin yoksa ve Spring Data Elasticsearch depolarını kullanıyorsanız veya bu depoları kullanmanız gerekiyorsa bu otomatik olarak gerçekleşir. IndexOperations.createWithMapping uygulamanızdaki işlev.

Fark ettiğim başka bir şey: farklı Spring Veri depoları için aynı varlık sınıfını kullanıyor ve ek açıklamaları yoğun bir şekilde karıştırıyorsunuz gibi görünüyor. Farklı mağazalar için farklı varlıklar kullanmalısınız.

2021-11-22 17:12:04

Kibana kullanarak eşleştirmeyi silmeyi denedim: Teklifi sil / _mapping ve tekliflerimi yeniden indeksleme. Ama belki açık bir "createWithMapping" kullanmak daha iyi sonuç verebilir, bu yardımcı olursa size bildiririm ! Yine de teşekkürler
Aymane EL Jahrani

Merhaba, bu yüzden createWithMapping kullanmayı denedim, ancak basit görünmüyor. Bunun doğru kullanım şekli olduğunu doğrulayabilir misiniz ? github.com/spring-projects/spring-data-elasticsearch/blob/main/...
Aymane EL Jahrani
0

ADIM ÇÖZMEK :

  • SİLDİĞİNİZDEN emin olmak için Kibana kullanın < index_name> / _mapping
  • Bir @JsonİgnoreProperties içinde olabilecek ihtiyacınız olan nesneler için varlık sınıflarınıza bakın
  • toMany ilişkinizin niteliklerini hevesle yüklediğinizden emin olun (aksi takdirde elastic, hiç vermediğiniz bir veri için eşleme oluşturmaz)
  • Bu küçük deneyimden, iç içe geçmiş alanları kullanmaktan kaçının derim, bunları kullanmanın herhangi bir avantajını göremedim. Bu yüzden sizin için de geçerli olup olmadığını kontrol edin !
2021-11-25 23:17:34

Spring Data Elasticsearch dos ile hiçbir şey yapmaz @JsonIgnoreProperties açıklama. Elasticsearch ilişkisel bir veritabanı değildir ve varlıklar arasındaki ilişkiler hakkında hiçbir fikri yoktur.
P.J.Meisch

Bu doğru, ancak spring verileri seri hale getirirken bunu yapıyor. Varlıklarımı böyle elde ederim ...
Aymane EL Jahrani

Baharın kendisi bunu yapmaz. Örneğin Spring Data JPA bunu yapar. Spring Data Elasticsearch bunu yapmaz. Bunlar farklı Yay Veri modülleridir.
P.J.Meisch

Fasterxml kütüphanesi.jackson bunu yapar ve JPA / Hazırda Bekletme varlıklarındaki ek açıklamaları kullanarak çalışır. Kodumda gördüğünüz gibi bu projede kullandığım şey bu...
Aymane EL Jahrani

Diğer dillerde

Bu sayfa diğer dillerde

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