1

i'm here new in elastic and .net. Let's go to the point, i'm trying to get child when its parent executed with has child query. I have read some article, and it said i can use inner hits to return child and parent together. So i wrote the json query and it ran successfully. However, when the query converted to NEST, it can't return the inner hits result. You could see json query (GET API) in "Search Query 1" and NEST query in "Search Query 2".

All information is described below:

Index
GET music

{
  "music" : {
    "aliases" : { },
    "mappings" : {
      "properties" : {
        "artist_relationship" : {
          "type" : "join",
          "eager_global_ordinals" : true,
          "relations" : {
            "song" : "user",
            "artist" : "song"
          }
        },
        "name" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "song" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        },
        "user" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "type" : "keyword",
              "ignore_above" : 256
            }
          }
        }
      }
    },
    "settings" : {
      "index" : {
        "routing" : {
          "allocation" : {
            "include" : {
              "_tier_preference" : "data_content"
            }
          }
        },
        "number_of_shards" : "1",
        "provided_name" : "music",
        "creation_date" : "1648194806610",
        "number_of_replicas" : "0",
        "uuid" : "Ps-cumUnRcKmTt6QDudZUA",
        "version" : {
          "created" : "7140099"
        }
      }
    }
  }
}
Add parents
POST music/_bulk    
{"index":{"_id":1}}
{"name":"John Legend","artist_relations":{"name":"artist"}}
{"index":{"_id":2}}
{"name":"Ariana Grande","artist_relations":{"name":"artist"}}
Add children
PUT music/_doc/3?routing=1
{"song":"All of Me","artist_relations":{"name":"song","parent":1}}
PUT music/_doc/4?routing=1
{"song":"Beauty and the Beast","artist_relations":{"name":"song","parent":1}}
PUT music/_doc/5?routing=2
{"song":"Beauty and the Beast","artist_relations":{"name":"song","parent":2}}
Add grandchildren
POST music/_bulk?routing=3
{"index":{"_id":"l-1"}}
{"user":"Gabriel","artist_relations":{"name":"user","parent":3}}
{"index":{"_id":"l-2"}}
{"user":"Berte","artist_relations":{"name":"user","parent":3}}
{"index":{"_id":"l-3"}}
{"user":"Emma","artist_relations":{"name":"user","parent":3}}

POST music/_doc/l-4?routing=4
{"user":"Berte","artist_relations":{"name":"user","parent":4}}
POST music/_doc/l-5?routing=5
{"user":"Emma","artist_relations":{"name":"user","parent":5}}
Model Mapping
public abstract class ArtistRelationship
{
    public JoinField artist_relationship { get; set; }
}

public class Artist : ArtistRelationship
{
    public string name { get; set; }
}

public class Song : ArtistRelationship
{
    public string song { get; set; }
}
Search Query 1
GET music/_search

{
  "query": {
    "has_child": {
      "type": "song",
      "min_children": 1,
      "max_children": 10,
      "query": {
        "match_all": {}
      },
      "inner_hits": {}
    }
  }
}
Search Query 2
var response = client.Search<Artist>(sd => sd
  .Index("music")
  .Query(qcd => qcd
    .HasChild<Song>(hc => hc
      .MinChildren(1)
      .MaxChildren(10)
      .Query(qcd2 => qcd2
        .MatchAll()
      )
      .InnerHits()
    )
  )
);
Output: please check this link

As you can see on the output, from "Search Query 1" i got song called "All of me" but in the right side (Search Query 2), i couldn't find any key containing "All of me" value.

I have checked all object and only got "_id". When compared to output from Search Query 1, the results are similar. Both query returned "3" value.

I'm not sure i'm wrong on model mapping, because i have followed the docs instruction (https://www.elastic.co/guide/en/elasticsearch/client/net-api/current/parent-child-relationships.html#_parent_and_child_example)

I'm sorry for bad english, i hope you all can understand . Thank you for taking your time and thanks in advance.

  • Did you already double-check, whether your NEST query translates to the desired query? You should be able to translate the NEST query to json somehow (https://stackoverflow.com/questions/28939022/get-raw-query-from-nest-client may be working, but could be outdated) – grek40 Mar 30 '22 at 08:44
  • @grek40 Hi grek, thanks for responding. Yes, I did (https://i.imgur.com/E0KE5C3.png). I thought this issue was a NEST issue, because there was a someone else who has similar problem and haven't got an answer till today (https://stackoverflow.com/questions/71516345/how-to-get-inner-hits-field-values-in-nest-or-elastic-net-library-alterantivly). – Muhammad Naufal Mar 31 '22 at 02:14
  • Have a look at https://stackoverflow.com/a/38287679/5265292. I think you just need to access the right properties of your result - it looks like NEST response will not prepare the type of your nested result for you, even though the query contains a strongly typed `HasChild`. Instead you have to know your nested types when reading the response. – grek40 Mar 31 '22 at 06:45
  • There is no "Type()" method available in inner hits descriptor (https://i.imgur.com/qAMAUUm.png). I think it might be outdated. Anyway, today I realize that NEST actually have returned inner hits in ASCII (https://i.imgur.com/bAZ8xxU.png) but I don't know how to convert it to object or other type. Still looking for the best practice. – Muhammad Naufal Apr 01 '22 at 06:52
  • Can you try to use `.InnerHits(h => h.Name("hello"))` in order to make your inner hits accessible with the "hello" name in the search response? Then get the inner hits per result like `hit.InnerHits["hello"].Hits.Documents()` – grek40 Apr 01 '22 at 07:17
  • @grek40 Finally! thanks a lot grek (https://i.imgur.com/M5EYYNn.png). – Muhammad Naufal Apr 01 '22 at 08:00
  • Glad I was able to help... I'm not using the parent-child relations myself, so I couldn't write an answer that "just works". Maybe if you find some time you can explain your solution as an answer for others. – grek40 Apr 01 '22 at 08:40

1 Answers1

0

I was able to fetch the document via below code block:

.InnerHits[IndexName].Hits.Hits[0].Source.AsAsync().Result

You can loop through all the documents in the collection.