如何向我的 React 应用程序添加搜索功能?

问题描述 投票:0回答:1

我正在尝试向我的 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) {}
}
reactjs mongodb search
1个回答
0
投票

搜索期间出错:MongoServerError:$text需要文本索引 查询

错误提示 $text 需要索引。

请参阅以下操作日志,重现相同的问题,并通过创建文本索引来解决。

  1. 语句第 1 行尝试执行全文搜索,但由于不存在文本索引而失败。

  2. 语句第 2 行在四个键 a、b、c 和 d 上创建文本索引。

  3. 语句第 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' }
     ]
    
© www.soinside.com 2019 - 2024. All rights reserved.