How to process the nest object (from ES response) in search-ui

I now this is for App Search, but not sure where to post this search-ui for elasticsearch question.

In a hard way that I learned that search-ui is expecting the 'id' field in the elasticsearch index hence the response. The problem is that the index is created by another program which does not have 'id', though it has the '_id' field.

In the buildState.js file, I am able to convert '_id' to 'id', but for this reason, I have to use the 'record' instead of 'record._source'. With this, the result set returns the _source as this:

"_source": [object Object]

while 'id' is normal:

"id": cee86628eaebffb36d3378be7a94651

So, how can I get the field inside the '_source' object?

Here is the code from buildState.js:

  const res = hits.map(record => {
    return Object.entries(record)
      .map(([fieldName, fieldValue]) => [
        fieldName == "_id" ? "id" : fieldName,
        toObject(fieldValue, getHighlight(record, fieldName))
      ])
      .reduce(addEachKeyValueToObject, {});
  });

Here is the state returned by buildState.js, and you can see it is an object.:

{
	"id": {
		"raw": "8239827cd9e538e88a03f71d2c8ae14"
	},
	"_index": {
		"raw": "myfirstfsjob"
	},
	"_score": {
		"raw": 9.116072
	},
	"_source": {
		"raw": {
			"content": "XXX",
			"file": {
				"filename": "dt4_8.pdf",
				"url": "c:\\dt4_8.pdf"
			}
		}
	}
}

Hey @Nee_Defeng,

When using Elasticsearch (as opposed to App Search) with Search UI, there's a bit more work involved, because there is not an out of the box connector to create requests and process responses. It is up to you to write that code. We do provide a nice example to get you started, as you saw, but is not expected to work in every case.

The responsibility of that buildState.js file is to convert an Elasticsearch response into a state object that Search UI understands.

So, in this case, you would need to adapt that code to return your response to be an object with fields that you need to use in your UI. Something like:

{
	"id": {
		"raw": "8239827cd9e538e88a03f71d2c8ae14"
	},
	"_index": {
		"raw": "myfirstfsjob"
	},
	"_score": {
		"raw": 9.116072
	},
	"content": {
		"raw": "XXX"
	},
	"file_filename": {
		"raw": "dt4_8.pdf"
	},
	"file_url": {
		"raw": "c:\\dt4_8.pdf"
	}
}

Let me know whether this makes sense to you or not.

It makes sense, absolutely.

I guess now I need to seek the help from React community for adapting the ES response into what EUI expects. BTW, I am new to React hence I am struggling with this.

Thanks,

OK, I think I got it now, the idea is to construct the new structure after destructuring from the old record:

 return hits.map(record => {
    const {
      _id: id,
      _score,
      _source: {
        content,
        file: { url, filename }
      },
      highlight: { content: highlighted }
    } = record;
   // console.log("this is destructre:", id, _score, url, filename, highlighted);
    const new_record = { id: id, title: filename, url, highlighted };
    return Object.entries(new_record)
      .map(([fieldName, fieldValue]) => [
        fieldName,
        toObject(fieldValue, getHighlight(new_record, fieldName))
      ])
      .reduce(addEachKeyValueToObject, {});
  });
}

Now I have the issue of displaying the highlighted text in the UI, it is not shown as the yellow highlighted text, but like this:

weather<em>is</em> metadata <em>Scanner</em> like this

Any advice?

One more question about the onAutocompleteResultClick function, I am trying to mimic what onSearch function is doing,

  onAutocompleteResultClick: async state => {
    const { resultsPerPage, documentId } = state;
    const requestBody = buildRequest(state);
    const responseJson = await runRequest(requestBody);
    return buildState(responseJson, 20);
  }

And I managed to invoke the buildState(responseJson,20) function and the console.log of the results shown as below:
[
{
"id": {
"raw": "d268283745ae7a7de62f3a8df78b44"
},
"title": {
"raw": "WIKI_Sydney"
},
"url": {
"raw": "http://localhost:8080/INFA/MyOwn/MyKnowledge/WIKI_Sydney"
},
"highlighted": {}
}
]

However, the search result is not refreshed, still shown the previous result.

What do I miss?