# Searching in nested lists

**URL:** <https://discourse.hibernate.org/t/searching-in-nested-lists/7732>\
**Category:** Hibernate Search\
**Created:** [June 1, 2023, 11:16am UTC](https://discourse.hibernate.org/t/searching-in-nested-lists/7732 "2023-06-01T11:16:48Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tony](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/tony/32/2448_2.png) [@Tony](https://discourse.hibernate.org/u/Tony)\
**Post date:** [June 1, 2023, 11:16am UTC](https://discourse.hibernate.org/t/searching-in-nested-lists/7732/1 "2023-06-01T11:16:48Z")

</div>

Hello to all,  
I have 3 objects A, B, C

```auto
public class A {
     private List<B> bList
}

public class B {
     private List<C> bList;
     private BigInteger testId;
}

public class C {
     private BigInteger type;
}

```

I would like to get documents where B.testId= {$id} and C.type != {$type} or C.type not exist.  
So, i am trying to do something like this

```auto
//or not exist c.type
pf.bool().should(pf.bool().mustNot(pf.exists().field("C.type")))
					)
					// or:
					// if B.testId != null and B.testId == {$id} and c.type != {type}
					.should(
							pf.bool().must(pf.match().field("B.testId").matching(new BigInteger(value)))
									.mustNot(pf.match().field("C.type").matching(type))
					).toPredicate();

```

But i cant get the correct result. The problem is that there is a confusion if i have \>1 records of class B with different testIds.

Thank you

---

<div class="post-metadata">

**Author:** ![yrodiere](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/yrodiere/32/1760_2.png) [@yrodiere](https://discourse.hibernate.org/u/yrodiere)\
**Post date:** [June 1, 2023, 11:26am UTC](https://discourse.hibernate.org/t/searching-in-nested-lists/7732/2 "2023-06-01T11:26:49Z")

</div>

I think you will find this section of the documentation relevant:

> **[Hibernate Search 6.1.8.Final: Reference Documentation](https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#mapper-orm-indexedembedded-structure)**
>
> Hibernate Search, full text search for your entities - Reference Documentation

In short, you’ll need to use [`@IndexedEmbedded(structure = NESTED)`](https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#mapper-orm-indexedembedded-structure-nested) and the [`nested` predicate](https://docs.jboss.org/hibernate/stable/search/reference/en-US/html_single/#search-dsl-predicate-nested)

---

<div class="post-metadata">

**Author:** ![Tony](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/tony/32/2448_2.png) [@Tony](https://discourse.hibernate.org/u/Tony)\
**Post date:** [June 1, 2023, 11:47am UTC](https://discourse.hibernate.org/t/searching-in-nested-lists/7732/3 "2023-06-01T11:47:52Z")

</div>

Thank you for your answer !

I add @IndexedEmbedded(structure = ObjectStructure.NESTED) so my new objects are

```auto
public class A {
     @IndexedEmbedded(structure = ObjectStructure.NESTED, includePaths = {"testId", "cList.type");
     private List<B> bList
}

public class B {
    @IndexedEmbedded(structure = ObjectStructure.NESTED, includePaths = {"type");
     private List<C> cList;
     private BigInteger testId;
}

public class C {
     @GenericField(sortable = Sortable.YES)
     private BigInteger type;
}

```

Again my results are not correct.

```auto
searchPredicate = pf.nested().objectField("bList.cList").nest(pf.bool()
				.must(pf.match().field("bList.testId").matching(new BigInteger(value)))
					.mustNot(pf.match().field("bList.cList.type").matching(type)
					)).toPredicate();

```

I am not sure about this **objectField(“bList.cList”)**

---

<div class="post-metadata">

**Author:** ![yrodiere](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/yrodiere/32/1760_2.png) [@yrodiere](https://discourse.hibernate.org/u/yrodiere)\
**Post date:** [June 1, 2023, 11:54am UTC](https://discourse.hibernate.org/t/searching-in-nested-lists/7732/4 "2023-06-01T11:54:01Z")

</div>

> [@Tony](#):
>
> I am not sure about this **objectField(“bList.cList”)**

Neither am I, `objectField("bList")` probably would make more sense here?

Anyway, I can’t really help if all the information you give is “my results are not correct”. If this still doesn’t work, at least give me an example dataset, the result you expect, and the results you’re getting.

---

<div class="post-metadata">

**Author:** ![Tony](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/tony/32/2448_2.png) [@Tony](https://discourse.hibernate.org/u/Tony)\
**Post date:** [June 1, 2023, 12:14pm UTC](https://discourse.hibernate.org/t/searching-in-nested-lists/7732/5 "2023-06-01T12:14:05Z")

</div>

i have 2 records on table B (1. with testid = 1 and 2. with testid = 2)  
i have 2 records on table C (1. with type = 1 and 2. with type = 2)

Object A contains both objects B and objectB contains both object C

i am on testid = 1, that it already contains the object C with type = 1, and i want to filter the document where type != 1. I am waiting to get 1 record(only type =2 ). so i use,

```auto
searchPredicate = pf.nested().objectField("bList").nest(pf.bool()
				.must(pf.match().field("bList.testId").matching(1)
					.mustNot(pf.match().field("bList.cList.type").matching(1)
					)).toPredicate();

```

The above return me always the records both **type = 1** and type = 2. The problem is the returned record with type = 1.

---

<div class="post-metadata">

**Author:** ![yrodiere](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/yrodiere/32/1760_2.png) [@yrodiere](https://discourse.hibernate.org/u/yrodiere)\
**Post date:** [June 1, 2023, 12:21pm UTC](https://discourse.hibernate.org/t/searching-in-nested-lists/7732/6 "2023-06-01T12:21:46Z")

</div>

> [@Tony](#):
>
> Object A contains both objects B and objectB contains both object C

Wait, there’s only one record in table `A`?

If so, you’re getting the expected result. Predicates determine which instances of `A` get returned, they don’t filter out the properties of `A`. You’ll just get an `A` with the exact same data that is in the database.

Returning to you a filtered view of A (e.g. in some DTO) that only includes the matching elements in `bList`/`cList` would require taking advantage of Elasticsearch’s [inner hits](https://www.elastic.co/guide/en/elasticsearch/reference/current/inner-hits.html#inner-hits-options), and that’s not currently supported ([[HSEARCH-4630] - Hibernate JIRA](https://hibernate.atlassian.net/browse/HSEARCH-4630)).

---

<div class="post-metadata">

**Author:** ![Tony](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/tony/32/2448_2.png) [@Tony](https://discourse.hibernate.org/u/Tony)\
**Post date:** [June 1, 2023, 12:25pm UTC](https://discourse.hibernate.org/t/searching-in-nested-lists/7732/7 "2023-06-01T12:25:50Z")

</div>

No, the tableA can have more than 1 records. I want to get object A with the above criteria of bList.testId and bList.cList.type.

---

<div class="post-metadata">

**Author:** ![yrodiere](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/yrodiere/32/1760_2.png) [@yrodiere](https://discourse.hibernate.org/u/yrodiere)\
**Post date:** [June 1, 2023, 12:33pm UTC](https://discourse.hibernate.org/t/searching-in-nested-lists/7732/8 "2023-06-01T12:33:50Z")

</div>

Okay, so what is your data like… ? Let me give a try:

- First instance of A
  - bList
    - First list element (type B)
      - testid = 1
      - cList
        - First list element (type C)
          - type = 1

- Second instance of A
  - bList
    - First list element (type B)
      - testid = 2
      - cList
        - First list element (type C)
          - type = 2

If that’s not the data you were trying to describe, please copy/paste the tree above and adapt it.

---

<div class="post-metadata">

**Author:** ![Tony](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/tony/32/2448_2.png) [@Tony](https://discourse.hibernate.org/u/Tony)\
**Post date:** [June 1, 2023, 12:41pm UTC](https://discourse.hibernate.org/t/searching-in-nested-lists/7732/9 "2023-06-01T12:41:04Z")

</div>

- First instance of A
  - bList
    - First list element (type B)
      - testid = 1
      - cList
        - First list element (type C)
          - type = 1

        - **Second list element (type C)**
          - **type = 2**

- Second instance of A
  - bList
    - First list element (type B)
      - testid = 2
      - cList
        - **First list element (type C)**
          - **type = 1**

        - Second list element (type C)
          - type = 2

and when i use the above searchpredicate i dont wait to return the record with type = 1 but it happens.

---

<div class="post-metadata">

**Author:** ![yrodiere](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/yrodiere/32/1760_2.png) [@yrodiere](https://discourse.hibernate.org/u/yrodiere)\
**Post date:** [June 1, 2023, 1:08pm UTC](https://discourse.hibernate.org/t/searching-in-nested-lists/7732/10 "2023-06-01T13:08:57Z")

</div>

Given that dataset, I wouldn’t expect any hit at all. The first instance of A shouldn’t match because there’s a C with type = 1, and the second instance of A shouldn’t match because the only B has testid = 2.

In fact I just ran a test, and that’s exactly the result I’m getting: [hibernate-test-case-templates/YourIT.java at discourse-7732-nestedlist · yrodiere/hibernate-test-case-templates · GitHub](https://github.com/yrodiere/hibernate-test-case-templates/blob/discourse-7732-nestedlist/search/hibernate-search-6/orm-lucene/src/test/java/org/hibernate/search/bugs/YourIT.java#L73-L74)

If you’re getting different results, please provide a reproducer.

---

<div class="post-metadata">

**Author:** ![Tony](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.hibernate.org/tony/32/2448_2.png) [@Tony](https://discourse.hibernate.org/u/Tony)\
**Post date:** [June 1, 2023, 1:13pm UTC](https://discourse.hibernate.org/t/searching-in-nested-lists/7732/11 "2023-06-01T13:13:05Z")

</div>

Thank you for your time. I will try it again and again. Thank you again ! 🙂
