如何使用 mongo 地理空间查询按用户距离对产品进行排序?

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

我正在开发一个网络应用程序,可以找到最近的用户(邻居)并显示他们想要购买的产品,他们也有能力销售。

该应用程序使用node.js、javaScript、mongodb、mongoose。

我的问题是对产品进行分类。我想显示从登录用户最近的用户到最远的用户排序的产品,但这没有发生,产品未排序。我花了几个小时,但我就是不明白出了什么问题

const Product = require('../models/products')
const User = require('../models/user')

module.exports.index = async (req, res) => {
    try {
        // get logged in user location
        const currentUserLocation = req.user.location.coordinates;

        // sorting users
        const nearbyUsers = await User.find({
            location: {
                $near: {
                    $geometry: {
                        type: 'Point',
                        coordinates: currentUserLocation
                    },
                }
            }
        });

        // Get products of nearby users
        const products = await Product.find({ author: { $in: nearbyUsers.map(user => user._id) } });
        console.log("this is the users log: ",nearbyUsers)
        console.log('this is the products log: ',products)
    



        // Render the products on the main page
        res.render('products/index', { products });
    } catch (error) {
        console.error('Error fetching nearby products:', error);
        res.status(500).send('Internal Server Error');
    }
};

用户模型

const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const passportLocalMongoose = require('passport-local-mongoose');
const Product = require("../models/products")

const UserSchema = new Schema({
    email: {
        type: String,
        required: true,
        unique: true
     },
     phoneNumber: Number,
   
     location: {
         type: {
           type: String,
            enum: ['Point'],
          required:true
    },
     coordinates: {
             type: [Number],
             required:true
         }
    
}})

UserSchema.index({ location: '2dsphere' }); 

UserSchema.plugin(passportLocalMongoose);

module.exports = mongoose.model('User', UserSchema);

产品型号

const mongoose = require("mongoose");
const Schema = mongoose.Schema;

const productSchema = new Schema ({
    title:String,
    images:[
      {
        url:String,
      filename:String
    }
    ],
    price:Number,
    description:String,
   
    
   author:{
    type: Schema.Types.ObjectId,
    ref:'User'
 },
 transactionType: {
    type: String,
    enum: ['sell', 'rent'],
},
status: {
    type: String,
    enum: ['available', 'sold', 'pending'], 
    default: 'available' // Default status is available
},



});



module.exports=mongoose.model('Products',productSchema)

索引 ejs 文件

 <%- layout ('/layouts/boilerplate') %>
   <h1>all products</h1> 
   <div>
   <a href="/products/new">add a product</a>
   <a href="/products/borrowing-requests">View Borrowing Requests</a>
</div>
   <% for(let product of products) {%>
    <div class="card" mb-3>
       <div class="row">
        <div class="col-md-4">
            <img src="<%= product.images[0].url %>" class="img-fluid" alt="Product Image">        </div>
        <div class="col-md-8">
            <div class="card-body">
                <h5 class="card-title"><%= product.title %></h5>
                <p class="card-text"><%= product.price %></p>
                <p class="card-text">
                <small class="text-secondary"><%= product.description %></small>
            </p>
            <a class="btn btn-primary" href="/products/<%= product._id %>">view <%= product.title %> </a>
                        </div>
                
            </div>
        </div>
       </div>
    </div>
<% } %>

路线

    router.route('/')
.get((products.index))

我认为这里的代码逻辑有问题,但我无法弄清楚,我已经提供了与问题相关的代码。

您认为有更好的方法来完成这项工作吗?我需要使用类似于使用mapbox之类的代码吗?

如果您有任何建议,请告诉我

注意:用户的坐标已在数据库中

javascript node.js mongodb mongoose product
1个回答
0
投票

在下面显示的现有代码中,附近的用户(按从最近到最远排序)将可用。这种排序顺序非常重要,因为产品必须基于相同的顺序列出。

// sorting users 
const nearbyUsers = await User.find({ location: { $near: { $geometry: { type: 'Point', coordinates: currentUserLocation }, } } }); 

在下面的代码中,将使用附近用户的数组来检索产品。因此,将提供产品列表。现在的问题是 - 所需的排序顺序尚未应用于此列表。

// Get products of nearby users 
const products = await Product.find({ author: { $in: nearbyUsers.map(user => user._id) } }); 
console.log("this is the users log: ",nearbyUsers) 
console.log('this is the products log: ',products) 

这至少可以通过两种方式完成。

  1. 在路由处理程序中编码:检索附近的用户和产品后,添加一些代码将附近用户的订单也更新到产品文档中,然后根据新添加和更新的订单键和订单键的组合对产品文档进行排序产品描述。这将导致产品按附近的用户和产品排序。

  2. 编写一个新的聚合查询:这个新的聚合查询应该有两个阶段,第一个阶段是查找附近的用户,第二个阶段是查找产品。由于第一阶段将根据用户的位置进行排序,因此在第二阶段中,产品应按相同的顺序进行整理。该需求查询最终将把现有的两个单独的查询(附近的用户和产品)合并为一个。

© www.soinside.com 2019 - 2024. All rights reserved.