我正在尝试向我的 React 应用程序添加一个搜索页面。我希望它有一个输入框、一个搜索按钮,输入内容后它将显示整个数据集的数据所在。因此,如果我搜索“例如 Jane Smith,我希望它能够为我提供数据库中不同集合中 Jane smith 的完整详细信息: 逮捕证 3721538 逮捕日期 2023-07-22T14:45:00.000+00:00 逮捕官 “约翰逊警官” 嫌疑人姓名 “简·史密斯” 罪行 “破坏公物” 我的数据库中有 3 个集合,并且希望搜索从集合中获取数据。我不知道如何使用 MongoDB Atlas 搜索,因此我尝试从应用程序中显示数据的页面中获取数据: 这是我的尝试:
import React, { useState } from 'react';
import axios from 'axios';
const SearchPage = () => {
const [searchTerm, setSearchTerm] = useState('');
const [searchResults, setSearchResults] = useState([]);
const [loading, setLoading] = useState(false);
const [error, setError] = useState('');
const handleSearch = async () => {
try {
setLoading(true);
setError('');
const response = await axios.get(`/api/search?q=${searchTerm}`);
setSearchResults(response.data);
} catch (error) {
setError('An error occurred while fetching search results.');
console.error(error);
} finally {
setLoading(false);
}
};
return (
<div>
<h1>Search Page</h1>
<div>
<input
type="text"
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
placeholder="Enter search term"
/>
<button onClick={handleSearch} disabled={loading}>Search</button>
</div>
{loading && <p>Loading...</p>}
{error && <p>{error}</p>}
<div>
<h2>Search Results</h2>
<ul>
{searchResults.map((result, index) => (
<li key={index}>
<strong>Collection:</strong> {result.collection}<br />
<strong>Result:</strong> {JSON.stringify(result)}
</li>
))}
</ul>
</div>
</div>
);
};
export default SearchPage;
这是我的后端代码的摘录:
// Routes to retrieve data
app.get('/api/vehicle_records', (req, res) => getRecords(req, res, 'vehicle_records'));
app.get('/api/arrest_records', (req, res) => getRecords(req, res, 'arrest_records'));
app.get('/api/crime_reports', (req, res) => getRecords(req, res, 'crime_reports'));
async function getRecords(req, res, collectionName) {
try {
await connectToMongoDB();
const records = await client.db("aless").collection(collectionName).find().toArray();
res.json(records);
// Broadcast data to WebSocket clients
wss.clients.forEach((client) => {
if (client.readyState === WebSocket.OPEN) {
client.send(JSON.stringify(records));
}
});
} catch (error) {
console.error(`Error retrieving ${collectionName}:`, error);
res.status(500).json({ message: `Error retrieving ${collectionName} data: ${error.message}` });
}
}
// Endpoint to handle adding data
app.post('/api/addData/:dataType', async (req, res) => {
try {
const dataType = req.params.dataType;
const data = req.body;
let collectionName;
switch (dataType) {
case 'crime':
collectionName = 'crime_records';
break;
case 'arrest':
collectionName = 'arrest_records';
break;
case 'vehicle':
collectionName = 'vehicle_records';
break;
default:
return res.status(400).json({ message: 'Invalid data type' });
}
await connectToMongoDB();
const result = await client.db("aless").collection(collectionName).insertOne(data);
console.log(`${dataType} data added successfully:`, result.insertedId);
res.status(201).json({ message: `${dataType} data added successfully`, insertedId: result.insertedId });
} catch (error) {
console.error(`Error adding ${req.params.dataType} data:`, error);
res.status(500).json({ message: `Error adding ${req.params.dataType} data` });
}
});
app.get('/api/search', async (req, res) => {
try {
const searchQuery = req.query.q;
// Connect to MongoDB
await connectToMongoDB();
// Search all collections for records matching the query
const vehicleRecords = await client.db("aless").collection('vehicle_records').find({ $text: { $search: searchQuery } }).toArray();
const arrestRecords = await client.db("aless").collection('arrest_records').find({ $text: { $search: searchQuery } }).toArray();
const crimeReports = await client.db("aless").collection('crime_reports').find({ $text: { $search: searchQuery } }).toArray();
// Combine search results from all collections
const searchResults = [...vehicleRecords, ...arrestRecords, ...crimeReports];
res.json(searchResults);
} catch (error) {
console.error('Error during search:', error);
res.status(500).json({ message: 'Error during search' });
}
});
这是显示数据的页面之一:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import '../SharedStyle.css';
const ArrestRecords= () => {
const [arrestRecords, setArrestRecords] = useState([]);
useEffect(() => {
// Fetch arrest records from backend API
axios.get('/api/arrest_records')
.then(response => {
console.log(response);
setArrestRecords(response.data);
})
.catch(error => {
console.error('Error fetching arrest records:', error);
});
// Establish WebSocket connection
const socket = new WebSocket('ws://localhost:3000');
// Handle WebSocket messages
socket.onmessage = (event) => {
const newRecord = JSON.parse(event.data);
setArrestRecords(prevRecords => [...prevRecords, newRecord]);
};
// Clean up WebSocket connection on component unmount
return () => {
socket.close();
};
}, []);
return (
<div className="arrest-container">
<div className='header-container'>
<h1>Arrest Records</h1>
</div>
<table className="record-table">
<thead>
<tr>
<th>Arrest ID</th>
<th>Arrest Date</th>
<th>Arresting Officer</th>
<th>Suspect Name</th>
<th>Offence</th>
</tr>
</thead>
<tbody>
{arrestRecords.map((record, index) => (
<tr key={record._id.$oid || index}>
<td>{record?.['Arrest ID']}</td>
<td>{new Date(record?.['Arrest Date']).toLocaleString()}</td>
<td>{record?.['Arresting Officer']}</td>
<td>{record?.['Suspect Name']}</td>
<td>{record?.['Offence']}</td>
</tr>
))}
</tbody>
</table>
</div>
);
};
export default ArrestRecords;
当我查找某些内容并在控制台中收到此错误时,我没有得到任何结果:“搜索期间出错”。 有办法解决这个问题吗?我该如何继续? 感谢您的帮助! 这是服务器中的错误:
Connected to MongoDB
Error during search: MongoServerError: text index required for $text query
at Connection.sendCommand (C:\Users\momon\program\my-aless-app\node_modules\mongodb\lib\cmap\connection.js:281:27)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async Connection.command (C:\Users\momon\program\my-aless-app\node_modules\mongodb\lib\cmap\connection.js:304:26)
at async Server.command (C:\Users\momon\program\my-aless-app\node_modules\mongodb\lib\sdam\server.js:169:24)
at async executeOperation (C:\Users\momon\program\my-aless-app\node_modules\mongodb\lib\operations\execute_operation.js:126:16)
at async FindCursor._initialize (C:\Users\momon\program\my-aless-app\node_modules\mongodb\lib\cursor\find_cursor.js:55:26)
at async [kInit] (C:\Users\momon\program\my-aless-app\node_modules\mongodb\lib\cursor\abstract_cursor.js:454:27)
at async next (C:\Users\momon\program\my-aless-app\node_modules\mongodb\lib\cursor\abstract_cursor.js:514:13)
at async [Symbol.asyncIterator] (C:\Users\momon\program\my-aless-app\node_modules\mongodb\lib\cursor\abstract_cursor.js:160:34)
at async FindCursor.toArray (C:\Users\momon\program\my-aless-app\node_modules\mongodb\lib\cursor\abstract_cursor.js:273:26) {
errorResponse: {
ok: 0,
errmsg: 'text index required for $text query',
code: 27,
codeName: 'IndexNotFound',
'$clusterTime': {
clusterTime: new Timestamp({ t: 1713777560, i: 1 }),
signature: [Object]
},
operationTime: new Timestamp({ t: 1713777560, i: 1 })
},
ok: 0,
code: 27,
codeName: 'IndexNotFound',
'$clusterTime': {
clusterTime: new Timestamp({ t: 1713777560, i: 1 }),
signature: {
hash: Binary.createFromBase64('fTs93PA/cG4eV1eaXx9qh0aYOTs=', 0),
keyId: new Long('7343629009340596229')
}
},
operationTime: new Timestamp({ t: 1713777560, i: 1 }),
[Symbol(errorLabels)]: Set(0) {}
}
搜索期间出错:MongoServerError:$text需要文本索引 查询
错误提示 $text 需要索引。
请参阅以下操作日志,重现相同的问题,并通过创建文本索引来解决。
语句第 1 行尝试执行全文搜索,但由于不存在文本索引而失败。
语句第 2 行在四个键 a、b、c 和 d 上创建文本索引。
语句第 3 行成功并生成结果,因为现在有一个文本索引支持此搜索。
// Using MongoDB: 7.0.2
// Using Mongosh: 2.1.1
use test
test> t = db.test
test> t.drop(); // optional step
test> t.insertMany([{a:"A"},{b:"B"},{c:"C"},{d:"D"}]);
{
acknowledged: true,...
}
test> t.find();
[
{ _id: ..., a: 'A' },
{ _id: ..., b: 'B' },
{ _id: ..., c: 'C' },
{ _id: ..., d: 'D' }
]
// line 1
test> t.find({$text:{$search:'AA DD'}});
MongoServerError: text index required for $text query
// line 2
test> t.createIndex({a:"text",b:"text",c:"text",d:"text"});
a_text_b_text_c_text_d_text
// line 3
test> t.find({$text:{$search:'AA DD'}});
[
{ _id: ..., a: 'AA' },
{ _id: ..., d: 'DD' }
]