【发布时间】:2021-12-11 23:30:07
【问题描述】:
我想从 mongoDB 数据库中获取与我在搜索栏中键入的关键字匹配的记录(哪些是车辆广告),并将它们显示在 reactJS 前端。记录的数据库架构(车辆广告)由 (制造、地址、注册、年份、intcolor、extcolor、transmission、bodytype、category、model) 等字段组成。因此,如果用户在搜索栏中输入类似 Toyota in Lahore 的内容,则用户应该会获得 make 是 toyota 和 address 是 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;
目前我的代码的工作方式是,如果我键入单个关键字,例如类型(丰田),它将向我显示所有带有 make=toyota 的车辆广告,如果我键入(拉合尔)它会向我显示所有带有 address=Lahore 的车辆广告。但是当我输入(拉合尔的丰田)时,它什么也没有显示
【问题讨论】:
-
嗨 - 您期望的功能无法直接使用 MongoDB。为此,您将需要 ElasticSearch。但是对于 MongoDB,您可以使其与
const mads = await Ads.find({ $text: { $search: "Toyota -in Lahore" } });一起使用,mongodb 将过滤掉开头带有-的单词。
标签: javascript node.js reactjs mongodb