【问题标题】:How to find records from database according to the typed string in the ReactJS search bar如何根据 ReactJS 搜索栏中键入的字符串从数据库中查找记录
【发布时间】:2021-12-11 23:30:07
【问题描述】:

我想从 mongoDB 数据库中获取与我在搜索栏中键入的关键字匹配的记录(哪些是车辆广告),并将它们显示在 reactJS 前端。记录的数据库架构(车辆广告)由 (制造、地址、注册、年份、intcolor、extcolor、transmission、bodytype、category、model) 等字段组成。因此,如果用户在搜索栏中输入类似 Toyota in Lahore 的内容,则用户应该会获得 ma​​ke 是 toyotaaddress 是 lahore 的所有记录(车辆广告)

这是我的前端代码

Homefilter.js(从搜索栏获取数据并将其保存在变量中,然后将其发送到另一个 searchAd.js 文件)

import React, { useEffect, useState } from 'react';
import './HeroSection.css';
import axios from 'axios';
import { useHistory } from 'react-router-dom';
import SearchAd from './SearchAd';

function Homefilter() {
  const [search, setSearch] = useState('');
  const history = useHistory();

  const Getsearch = () => {
    console.log(search);
    history.push(`/searchpage/${search}`);
  };

  return (
    <div class='container-fluid'>
      <div
        style={{ height: '350px', alignItems: 'center' }}
        class='row'
        id='colu'
      >
        <div class='col-lg-12 col-md-12 col-sm-12'>
          <div
            style={{
              justifyContent: 'center',
              alignContent: 'center',
              alignItems: 'center',
              textAlign: 'center',
            }}
          >
            <input
              style={{ display: 'inline', width: '35rem' }}
              type='text'
              name='search'
              class='form-control'
              placeholder='Enter keyword to search Vehicle'
              value={search}
              onChange={(e) => setSearch(e.target.value)}
            />
            <button onClick={Getsearch} class='btn btn-primary'>
              Search
            </button>
          </div>
        </div>
      </div>
    </div>
  );
}

export default Homefilter;

SearchAd.js(从 Homefilter.js 接收变量并在 GET 请求中将其发送到后端**

import React, { useEffect, useState } from 'react';

import axios from 'axios';
import './Allads.css';
import { useParams } from 'react-router-dom';

const SearchAd = () => {
  const { search } = useParams();
  console.log(search);
  const [data, setData] = useState('');
  const stringse = JSON.stringify(search);
  console.log(stringse);

  const Getsearch = () => {
    axios
      .get('/searchdata', { params: { stringse } })
      .then((response) => {
        setData(response.data.data);
        console.log(response);
      })
      .catch((error) => {
        console.log(error);
      });
  };

  useEffect(() => {
    Getsearch();
  }, []);

  if (data.length > 0) {
    return data.map((datas, index) => {
      console.log(datas);
      return (
        <div className='datas' key={datas._id}>
          <div style={{ marginTop: '20px' }} class='container-fluid'>
            <div class='row'>
              <div class='col-lg-1 col-md-1 col-sm-1 '></div>

              <div class='col-lg-4 col-md-4 col-sm-4 '>
                <div
                  style={{ backgroundColor: '#1c2237', height: '180px' }}
                  class='row'
                >
                  <div class='col-lg-12 col-md-12 col-sm-12'>
                    <h3 style={{ color: '#f00946' }}>
                      {datas.make} {datas.model}
                    </h3>
                    <p>
                      <b>{datas.location.formattedAddress}</b>
                    </p>
                    <p>
                      {datas.year} | {datas.mileage} Km | interior:{' '}
                      {datas.intcolor} | exterior: {datas.extcolor} |{' '}
                      {datas.engine} cc | {datas.transmission} |
                      {datas.registeration} Registered | {datas.bodytype} |{' '}
                      {datas.category}
                    </p>
                    <p>Updated: {datas.createdAt} </p>
                  </div>
                </div>

                <div
                  style={{ backgroundColor: '#f00946', height: '180px' }}
                  class='row'
                >
                  <div class='col-lg-12 col-md-12 col-sm-12'>
                    <h5 style={{ color: '#1c2237' }}> PKR: {datas.price} </h5>
                    <p style={{ marginTop: '70px' }}>
                      <b>mob #:</b>
                      {datas.mobilenumber}
                    </p>
                  </div>
                </div>
              </div>

              <div class='col-lg-6 col-md-6 col-sm-6 '>
                <div style={{ backgroundColor: 'white' }} class='row'>
                  <div class='col-lg-4 col-md-4 col-sm-4  '>
                    <img
                      className='zoomimg'
                      src={`http://localhost:3000/uploads/profilepics/${datas.images[0]}`}
                      alt='abc'
                    />
                  </div>
                  <div
                    style={{ paddingRight: '100px' }}
                    class='col-lg-4 col-md-4 col-sm-4 '
                  >
                    <img
                      className='zoomimg'
                      src={`http://localhost:3000/uploads/profilepics/${datas.images[1]}`}
                      alt='abc'
                    />
                  </div>
                  <div class='col-lg-4 col-md-4 col-sm-4 '>
                    <img
                      className='zoomimg'
                      src={`http://localhost:3000/uploads/profilepics/${datas.images[2]}`}
                      alt='abc'
                    />
                  </div>
                </div>

                <div style={{ backgroundColor: 'white' }} class='row'>
                  <div class='col-lg-4 col-md-4 col-sm-4 '>
                    {' '}
                    <img
                      className='zoomimg'
                      src={`http://localhost:3000/uploads/profilepics/${datas.images[3]}`}
                      alt='abc'
                    />
                  </div>
                  <div class='col-lg-4 col-md-4 col-sm-4 '>
                    {' '}
                    <img
                      className='zoomimg'
                      src={`http://localhost:3000/uploads/profilepics/${datas.images[4]}`}
                      alt='abc'
                    />
                  </div>
                  <div class='col-lg-4 col-md-4 col-sm-4 '>
                    {' '}
                    <img
                      className='zoomimg'
                      src={`http://localhost:3000/uploads/profilepics/${datas.images[5]}`}
                      alt='abc'
                    />
                  </div>
                </div>
              </div>

              <div class='col-lg-1 col-md-1 col-sm-1 '></div>
            </div>
          </div>
        </div>
      );
    });
  } else {
    return <h3>no more ads</h3>;
  }
};

export default SearchAd;

后端代码

router.get('/searchdata', async (req, res, next) => {
  console.log(req.query.stringse);
  const searchad = req.query.stringse;

  try {
    const mads = await Ads.find({ $text: { $search: searchad } });
    console.log(mads);
    return res.status(200).json({
      success: true,
      count: mads.length,
      data: mads,
    });
  } catch (err) {
    console.log(err);
    res.status(500).json({ error: 'server error' });
  }
});

车辆广告架构

const mongoose = require('mongoose');
const geocoder = require('../utils/geocoder');

const adsSchema = new mongoose.Schema({
  registeration: {
    type: String,
    required: true,
    index: true,
  },

  intcolor: {
    type: String,
    required: true,
    index: true,
  },
  extcolor: {
    type: String,
    required: true,
    index: true,
  },
  mileage: {
    type: Number,
    required: true,
  },
  price: {
    type: Number,
    required: true,
  },
  make: {
    type: String,
    required: true,
    index: true,
  },
  model: {
    type: String,
    required: true,
    index: true,
  },
  year: {
    type: Number,
    required: true,
    index: true,
  },
  discription: {
    type: String,
    required: true,
  },
  mobilenumber: {
    type: Number,
    required: true,
  },

  address: {
    type: String,
    required: true,
    index: true,
  },
  images: {
    type: Array,
    required: true,
  },
  transmission: {
    type: String,
    required: true,
    index: true,
  },
  engine: {
    type: String,
    required: true,
  },
  userId: {
    type: String,
    required: true,
  },
  serial: {
    type: String,
    required: true,
  },
  bodytype: {
    type: String,
    required: true,
    index: true,
  },
  category: {
    type: String,
    required: true,
    index: true,
  },

  location: {
    type: {
      type: String,
      enum: ['MultiPoint'],
    },
    coordinates: {
      type: [Number],
      index: '2dsphere',
    },
    formattedAddress: {
      type: String,
    },
  },
  createdAt: {
    type: Date,
    default: Date.now,
  },
});

adsSchema.index({
  make: 'text',
  address: 'text',
  registeration: 'text',
  year: 'text',
  intcolor: 'text',
  extcolor: 'text',
  transmission: 'text',
  bodytype: 'text',
  category: 'text',
  model: 'text',
});
adsSchema.pre('save', async function (next) {
  const loc = await geocoder.geocode(this.address);
  this.location = {
    type: 'multipoint',
    coordinates: [loc[0].longitude, loc[0].latitude],
    formattedAddress: loc[0].formattedAddress,
  };
  next();
});

const Ads = mongoose.model('ADS', adsSchema);
module.exports = Ads;

目前我的代码的工作方式是,如果我键入单个关键字,例如类型(丰田),它将向我显示所有带有 ma​​ke=toyota 的车辆广告,如果我键入(拉合尔)它会向我显示所有带有 address=Lahore 的车辆广告。但是当我输入(拉合尔的丰田)时,它什么也没有显示

【问题讨论】:

  • 嗨 - 您期望的功能无法直接使用 MongoDB。为此,您将需要 ElasticSearch。但是对于 MongoDB,您可以使其与 const mads = await Ads.find({ $text: { $search: "Toyota -in Lahore" } }); 一起使用,mongodb 将过滤掉开头带有 - 的单词。

标签: javascript node.js reactjs mongodb


【解决方案1】:

试试这个:

import React, { useEffect, useState } from 'react';

import axios from 'axios';
import './Allads.css';
import { useParams } from 'react-router-dom';

const SearchAd = () => {
const { search } = useParams();
console.log(search);
const [data, setData] = useState('');

const Getsearch = () => {
    const searchSep = " in "
    const regEscape = v => v.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
    const searchArr = str.split(new RegExp(regEscape(searchSep), "ig"));
    const params = {};
    if (searchArr.length === 2) {
        params.query = {make: searchArr[0].trim(), address: searchArr[1].trim()};
    }
    
    axios
    .get('/searchdata', params)
    .then((response) => {
        setData(response.data.data);
        console.log(response);
    })
    .catch((error) => {
        console.log(error);
    });
};

useEffect(() => {
    if (search) {
        Getsearch();
    }
}, [search]);

if (data.length > 0) {
    return data.map((datas, index) => {
    console.log(datas);
    return (
        <div className='datas' key={datas._id}>
        <div style={{ marginTop: '20px' }} class='container-fluid'>
            <div class='row'>
            <div class='col-lg-1 col-md-1 col-sm-1 '></div>

            <div class='col-lg-4 col-md-4 col-sm-4 '>
                <div
                style={{ backgroundColor: '#1c2237', height: '180px' }}
                class='row'
                >
                <div class='col-lg-12 col-md-12 col-sm-12'>
                    <h3 style={{ color: '#f00946' }}>
                    {datas.make} {datas.model}
                    </h3>
                    <p>
                    <b>{datas.location.formattedAddress}</b>
                    </p>
                    <p>
                    {datas.year} | {datas.mileage} Km | interior:{' '}
                    {datas.intcolor} | exterior: {datas.extcolor} |{' '}
                    {datas.engine} cc | {datas.transmission} |
                    {datas.registeration} Registered | {datas.bodytype} |{' '}
                    {datas.category}
                    </p>
                    <p>Updated: {datas.createdAt} </p>
                </div>
                </div>

                <div
                style={{ backgroundColor: '#f00946', height: '180px' }}
                class='row'
                >
                <div class='col-lg-12 col-md-12 col-sm-12'>
                    <h5 style={{ color: '#1c2237' }}> PKR: {datas.price} </h5>
                    <p style={{ marginTop: '70px' }}>
                    <b>mob #:</b>
                    {datas.mobilenumber}
                    </p>
                </div>
                </div>
            </div>

            <div class='col-lg-6 col-md-6 col-sm-6 '>
                <div style={{ backgroundColor: 'white' }} class='row'>
                <div class='col-lg-4 col-md-4 col-sm-4  '>
                    <img
                    className='zoomimg'
                    src={`http://localhost:3000/uploads/profilepics/${datas.images[0]}`}
                    alt='abc'
                    />
                </div>
                <div
                    style={{ paddingRight: '100px' }}
                    class='col-lg-4 col-md-4 col-sm-4 '
                >
                    <img
                    className='zoomimg'
                    src={`http://localhost:3000/uploads/profilepics/${datas.images[1]}`}
                    alt='abc'
                    />
                </div>
                <div class='col-lg-4 col-md-4 col-sm-4 '>
                    <img
                    className='zoomimg'
                    src={`http://localhost:3000/uploads/profilepics/${datas.images[2]}`}
                    alt='abc'
                    />
                </div>
                </div>

                <div style={{ backgroundColor: 'white' }} class='row'>
                <div class='col-lg-4 col-md-4 col-sm-4 '>
                    {' '}
                    <img
                    className='zoomimg'
                    src={`http://localhost:3000/uploads/profilepics/${datas.images[3]}`}
                    alt='abc'
                    />
                </div>
                <div class='col-lg-4 col-md-4 col-sm-4 '>
                    {' '}
                    <img
                    className='zoomimg'
                    src={`http://localhost:3000/uploads/profilepics/${datas.images[4]}`}
                    alt='abc'
                    />
                </div>
                <div class='col-lg-4 col-md-4 col-sm-4 '>
                    {' '}
                    <img
                    className='zoomimg'
                    src={`http://localhost:3000/uploads/profilepics/${datas.images[5]}`}
                    alt='abc'
                    />
                </div>
                </div>
            </div>

            <div class='col-lg-1 col-md-1 col-sm-1 '></div>
            </div>
        </div>
        </div>
    );
    });
} else {
    return <h3>no more ads</h3>;
}
};

export default SearchAd;

但如果您的搜索文本中有多个in 短语,则它不起作用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-01-30
    • 2017-05-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-01-26
    • 2017-05-25
    相关资源
    最近更新 更多