Use @IndexedEmbedded for indexing only the first element of a list

Hello.
Is it possible to use @IndexedEmbedded only to index the first element of a list or one element with where condition?

    @OneToMany(mappedBy = "field", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
	@IndexedEmbedded(structure = ObjectStructure.NESTED, includePaths = {"id"})
	@IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW)
	private List<Object> list = new ArrayList<>();

Thank you

Hey, here’s an example from the documentation of how it can be done Filtering association elements

Instead of annotating the field, create a “getter” that returns the filtered data, or a single element and annotate this getter instead.

1 Like

Thank you for your answer. i will check it ! :slight_smile:

I have a terrible problem due to a high volume of data on children of my masters. I have 2 cases. 1st case a master object with a list that has 1000 records and 2nd case a master with a list that has one record. I would like to be able to do indexing dependency only for the second case. I thought of applying transient object as well, but again here it applies index to all the details.

    @OneToMany(mappedBy = "field", cascade = CascadeType.ALL, fetch = FetchType.LAZY, orphanRemoval = true)
	@IndexedEmbedded(structure = ObjectStructure.NESTED, includePaths = {"id"})
	@IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW)
	private List<Object> list = new ArrayList<>();
    
    ....

    @Transient
	@IndexingDependency(derivedFrom = {
			@ObjectPath(@PropertyValue(propertyName = "list"))
	}, reindexOnUpdate = ReindexOnUpdate.SHALLOW)
	@IndexedEmbedded(includePaths = {"id")
	private Object object;
	
	public Object getObject () {
		if (CollectionUtils.isNotNullOrEmpty(list)) {
			return list.get(0);
		}
		return null;
	}

well… from the shared code snippet

@IndexedEmbedded(structure = ObjectStructure.NESTED, includePaths = {"id"})
@IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW)
private List<Object> list = new ArrayList<>();

the list still has Search annotations, so it’ll get to the index. If only a single element should be indexed then remove these from the list field and only keep the getter as

  @Transient
	@IndexingDependency(derivedFrom = {
			@ObjectPath(@PropertyValue(propertyName = "list"))
	}, reindexOnUpdate = ReindexOnUpdate.SHALLOW)
	@IndexedEmbedded(includePaths = {"id")
	public Object getObject () {
		if (CollectionUtils.isNotNullOrEmpty(list)) {
			return list.get(0);
		}
		return null;
	}

no need for private Object object;

1 Like

will the above code apply index only to the first element of the list?
and if I update, will my master update the indexes only on the first element of the list or on the entire list?

Thank you for your help again and again ! :slight_smile:

I’m back to the topic.
I have a model that has several oneToMany relations. Some of them have thousands of records. I want to display a list from my master object but in the list i want to display a column that will contain the sum of all the debit of the detail, totalDebit, with the 1000 records.
Also the detail has another relationship oneToMany, detail2, with another 100 records each and I need to bring in the master list an “exist” column if there is a record in detail2.

i have used the following so that i can then filter or sort with column debit and column exist in the master list.

@Indexed
public class Master {
    ....
    private List<Detail1> detail1 = new ArrayList<>();

    @Transient
	@IndexingDependency(derivedFrom = {
			@ObjectPath({
					@PropertyValue(propertyName = "detail1"),
					@PropertyValue(propertyName = "debit")})
	}, reindexOnUpdate = ReindexOnUpdate.SHALLOW)
	public BigDecimal getTotalDebit () {
		BigDecimal debit = BigDecimal.ZERO;
		if (CollectionUtils.isNotNullOrEmpty(detail1)) {
			for (final Detail1 detail: detail1) {
				debit = debit .add(detail.getDebit() != null ? detail.getDebit() : BigDecimal.ZERO);
			}
		}
		return null;
	}

    @Transient
	@IndexingDependency(derivedFrom = {
			@ObjectPath({
					@PropertyValue(propertyName = "detail1"),
                    @PropertyValue(propertyName = "detail2"),
					@PropertyValue(propertyName = "id")})
	}, reindexOnUpdate = ReindexOnUpdate.SHALLOW)
	public int getExist () {
		if (CollectionUtils.isNotNullOrEmpty(detail1)) {
			for (final Detail detail: detail1) {
				if (CollectionUtils.isNotNullOrEmpty(detail1.getDetail2())) {
					return 1;
				}
			}
		}
        return 0;
	}
}

@Indexed
public class Detail1 {
    ....
    @IndexedEmbedded(structure = ObjectStructure.NESTED, includePaths = {"id"})
	@IndexingDependency(reindexOnUpdate = ReindexOnUpdate.SHALLOW)
    private List<Detail2> detail2 = new ArrayList<>();
}

In practice this means that whether I do mass indexing or update the master it will select the details due to the indexingDependency.
In mass action to save the master, about 500k master objects, leads to outOfMemory.

Thank you !

I will open new topic about the last issue ! Large data leads to OutOfMemory