Reputation: 13683
I have this api route
import { Client } from "@elastic/elasticsearch";
import { NextResponse } from "next/server";
export async function GET(request) {
try {
const client = new Client({ node: "http://localhost:9200" });
const { body } = await client.search({
index: "game-of-thrones",
size: 100,
body: {
query: {
match_all: {}
}
}
});
const hits = body.hits?.hits || [];
const documents = hits.map((hit) => hit._source);
return NextResponse.json(documents, { status: 200 });
} catch (error) {
console.error("Elasticsearch Error:", error);
return NextResponse.error();
}
}
and this client side page
'use client';
import { useEffect, useState } from 'react';
export default function Home() {
const [documents, setDocuments] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch('/api/all');
const data = await response.json();
setDocuments(data);
setLoading(false);
} catch (error) {
console.error('Error fetching documents:', error);
}
};
fetchData();
}, []);
return (
<main>
{loading ? (
<p>Loading...</p>
) : (
<div>
{documents.map((document) => (
<div key={document._id}>
<h2>{document.character}</h2>
<p>{document.quote}</p>
</div>
))}
</div>
)}
</main>
);
}
I am trying to read from an existing index but i keep getting this error
Elasticsearch Error: TypeError: Cannot read properties of undefined (reading 'hits')
at GET (webpack-internal:///(sc_server)/./src/app/api/all/route.js:24:27)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async eval (webpack-internal:///(sc_server)/./node_modules/next/dist/server/future/route-modules/app-route/module.js:244:37)
- error RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: 0
at new NodeError (node:internal/errors:399:5)
at ServerResponse.writeHead (node:_http_server:344:11)
at ServerResponse.writeHead (c:\admin\node_modules\next\dist\compiled\compression\index.js:46:263)
at ServerResponse._implicitHeader (node:_http_server:335:8)
at ServerResponse.end (c:\admin\node_modules\next\dist\compiled\compression\index.js:22:749)
at sendResponse (c:\admin\node_modules\next\dist\server\send-response.js:49:30)
at doRender (c:\admin\node_modules\next\dist\server\base-server.js:970:62)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async cacheEntry.responseCache.get.incrementalCache.incrementalCache (c:\admin\node_modules\next\dist\server\base-server.js:1162:28)
at async c:\admin\node_modules\next\dist\server\response-cache\index.js:99:36 {
code: 'ERR_HTTP_INVALID_STATUS_CODE'
}
My index looks like this
{"took":3,"timed_out":false,"_shards":{"total":1,"successful":1,"skipped":0,"failed":0},"hits":{"total":{"value":25,"relation":"eq"},"max_score":1.0,"hits":[{"_index":"game-of-thrones","_id":"XHsmMIgBAA3lxqgqah3Y","_score":1.0,"_source":{"character":"Ned Stark","quote":"Winter is coming."}},{"_index":"game-of-thrones","_id":"W3smMIgBAA3lxqgqaR0g","_score":1.0,"_source":{"character":"Ned Stark","quote":"Winter is coming."}},{"_index":"game-of-thrones","_id":"XXsmMIgBAA3lxqgqbB1T","_score":1.0,"_source":{"character":"Daenerys Targaryen","quote":"I am the blood of the dragon."}},{"_index":"game-of-thrones","_id":"XnsmMIgBAA3lxqgqbB3p","_score":1.0,"_source":{"character":"Tyrion Lannister","quote":"A mind needs books like a sword needs a whetstone."}},{"_index":"game-of-thrones","_id":"X3smMIgBAA3lxqgq7h3K","_score":1.0,"_source":{"character":"Ned Stark","quote":"Winter is coming."}},{"_index":"game-of-thrones","_id":"YHsmMIgBAA3lxqgq7x0h","_score":1.0,"_source":{"character":"Daenerys Targaryen","quote":"I am the blood of the dragon."}},{"_index":"game-of-thrones","_id":"YXsmMIgBAA3lxqgq7x2O","_score":1.0,"_source":{"character":"Tyrion Lannister","quote":"A mind needs books like a sword needs a whetstone."}},{"_index":"game-of-thrones","_id":"YnsmMIgBAA3lxqgq8R3R","_score":1.0,"_source":{"character":"Ned Stark","quote":"Winter is coming."}},{"_index":"game-of-thrones","_id":"Y3smMIgBAA3lxqgq8h0i","_score":1.0,"_source":{"character":"Daenerys Targaryen","quote":"I am the blood of the dragon."}},{"_index":"game-of-thrones","_id":"ZHsmMIgBAA3lxqgq8h12","_score":1.0,"_source":{"character":"Tyrion Lannister","quote":"A mind needs books like a sword needs a whetstone."}}]}}
How can i return the documents that i want?
Upvotes: 1
Views: 1481
Reputation: 13683
I have managed to fix it this way
Server
import { Client } from "@elastic/elasticsearch";
import { NextResponse } from "next/server";
export async function GET(request) {
try {
const client = new Client({ node: "http://localhost:9200" });
const { body } = await client.search({
index: "game-of-thrones",
query: {
match_all: {}
}
}, { meta: true });
console.log('body', body);
return NextResponse.json(body, { status: 200 });
} catch (error) {
console.error("Elasticsearch Error:", error);
return NextResponse.error();
}
}
Client
'use client';
import { useEffect, useState } from 'react';
export default function Home() {
const [documents, setDocuments] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch('/api/all');
const data = await response.json();
setDocuments(data.hits.hits.map((hit) => hit._source));
setLoading(false);
} catch (error) {
console.error('Error fetching documents:', error);
}
};
fetchData();
}, []);
return (
<main>
{loading ? (
<p>Loading...</p>
) : (
<div>
{documents.map((document, index) => (
<div key={index}>
<h2>{document.character}</h2>
<p>{document.quote}</p>
</div>
))}
</div>
)}
</main>
);
}
Upvotes: 1