private FunctionDescription querySingleDescriptionId(DescriptionManager manager, String rowId)
			throws ElasticException, LSHException {
		StringBuilder buffer = new StringBuilder();
		buffer.append("{ \"query\": { \"ids\": { \"values\": [ \"");
		buffer.append(rowId);
		buffer.append("\" ] } } }");
		JsonObject resp = connection.executeStatement(ElasticConnection.GET, "executable/_search",
			buffer.toString());
		JsonObject hits = (JsonObject) resp.get("hits");
		JsonObject totalRec = (JsonObject) hits.get("total");
		long total = totalRec.get("value").getAsLong();
		if (total == 0) {
			throw new ElasticException("No function documents matching id=" + rowId);
		}
		JsonArray hitsArray = (JsonArray) hits.get("hits");
		JsonObject row = (JsonObject) hitsArray.get(0);
		JsonObject source = (JsonObject) row.get("_source");
		JsonObject joinfield = (JsonObject) source.get("join_field");
		String exeId = joinfield.get("parent").getAsString();
		RowKeyElastic eKey = RowKeyElastic.parseExeIdString(exeId);
		ExecutableRecord exeRec = manager.findExecutableByRow(eKey);
		if (exeRec == null) {
			List<RowKeyElastic> keyList = new ArrayList<>();
			keyList.add(eKey);
			queryExecutableRecordById(manager, keyList.iterator(), keyList.iterator(), 2);
			exeRec = manager.findExecutableByRow(eKey);
		}
		return convertDescriptionRow(row, exeRec, manager, null);
	}
Given the document id for a specific function. Query for the document and
produce the corresponding FunctionDescription
@param manager is the container for the new FunctionDescription
@param rowId is the document id of the function
@return the new FunctionDescription
@throws ElasticException for communication problems with the server
@throws LSHException for problems adding records to the container
Ghidra/Features/BSim/src/main/java/ghidra/features/bsim/query/elastic/ElasticDatabase.java