1

I am trying to search for a text in elasticsearch using nest 7.10.1. I want to search in two different indexes, I get a response in the form of documents, but I cannot access its properties because the result has the combination of two indexes. Below is the code I tried. Both the indexes has same properties. What do I use in the foreach loop to access the key and values of the result documents.

public void searchIndices(string query) {
    var response = client.Search<object>(
      s => s.Index("knowledgearticles_index, index2")
            .Query(q => q.Match(m => m.Field("locationName")
                         .Query(query))));

    Console.WriteLine(response.Documents);
    
    foreach(object r in response.Documents) {
      
    }
}

I am using elasticsearch 7.10.2

Joe - GMapsBook.com
  • 15,787
  • 4
  • 23
  • 68

2 Answers2

1

Each raw hit coming back in the search response has the _index meta field associated with it:

"hits" : {
  "total" : {
    "value" : 91,
    "relation" : "eq"
  },
  "hits" : [
    {
      "_index" : "knowledgearticles_index",   <---
      "_type" : "_doc",
      "_id" : "r_oLl3cBZOT6A8Qby8Qd",
      "_score" : 1.0,
      "_source" : {
        ...
      }
    }

Now, in NEST,

.Documents is a convenient shorthand for retrieving the _source for each hit

-- meaning that you'll have lost access to the meta properties.

So the trick is to use a loop like this instead:

foreach (var hit in response.HitsMetadata.Hits) {
  Console.WriteLine(hit);
}
Joe - GMapsBook.com
  • 15,787
  • 4
  • 23
  • 68
  • Thank you for your reply. But, how do I access the values of each property. For example i want to retrieve all the documents from 2 indexes with a particular text. How to I retrieve them and print them on the console. – Komal Kartan Feb 15 '21 at 18:41
  • I am able to get response with 10 hits. My question is how do I access the values inside them and print them? – Komal Kartan Feb 15 '21 at 18:47
  • 1
    Updated my answer at the bottom. Hope it helps. – Joe - GMapsBook.com Feb 15 '21 at 18:51
  • my console looks like this now. Nest.Hit`1[System.Object] Nest.Hit`1[System.Object] Nest.Hit`1[System.Object] Nest.Hit`1[System.Object] Nest.Hit`1[System.Object] Nest.Hit`1[System.Object] Nest.Hit`1[System.Object] Nest.Hit`1[System.Object] Nest.Hit`1[System.Object] – Komal Kartan Feb 15 '21 at 19:11
  • I'm not too familiar w/ NEST to help you further... Printing objects to the console is out of scope if this question but [this answer](https://stackoverflow.com/a/28140778/8160318) may help. – Joe - GMapsBook.com Feb 15 '21 at 19:17
0

If the two indices that you're searching over contain different JSON structures, then the T in Search<T> will need to be a type that the differing JSON structures can be deserialize to. object will work as per the example in your question, but then there is no typed access for any of the properties.

A simple approach to overcoming this is to hook up the JsonNetSerializer and then use JObject for T

var pool = new SingleNodeConnectionPool(new Uri("http://localhost:9200"));
var connectionSettings =
    new ConnectionSettings(pool, sourceSerializer: JsonNetSerializer.Default);
var client = new ElasticClient(connectionSettings);

var response = client.Search<JObject>(s => s
    .Index("knowledgearticles_index, index2")
    .Query(q => q
        .Match(m => m
            .Field("locationName")
            .Query(query)
        )
     )
);

We now have a way of accessing properties on JObject, but will still need to handle the type of each property.

Russ Cam
  • 124,184
  • 33
  • 204
  • 266
  • @KomalKartan If it helped, please upvote. And if it solved the question, please mark as accepted :) – Russ Cam Feb 19 '21 at 12:31