我有一个要查询的集合用户,餐馆,产品,用户将在他/她的应用程序中看到附近的餐馆(5公里),其isOpen:true,并显示每个餐馆的产品isAvailable和isApproved = true和isArchived:false。
let kmToRadian = function(miles){
var earthRadiusInMiles = 6378
return miles / earthRadiusInMiles
}
var user = dbo.collection('users').findOne({_id: id})
var query = {
"location": {
$geoWithin: {
$centerSphere: [ [22.222, 22.222], 5 / 6378.1] //sample coordinates
}
}
}
db.products.aggregate([
{
$lookup: {
from: "restaurants",
localField: "restaurants",
foreignField: "_id",
as: "restaurant"
}
},
{
$match : {
"restaurant.isOpen": true,
"isApproved": true,
"isAvailable": true,
"isArchived": false
}
},
{
$project: {
"restaurant.isOpen": 1,
"isApproved": 1,
"isAvailable": 1,
"isArchived": 1,
"name": 1
}
}
])
在这里,我得到的产品是isAvailable,isApproved:true和isArchived false。现在,我想在附近找到5公里的餐厅。
收集用户
id: 1
name: "Robert"
location: Object
type: "Point",
coordinates: Array
0: 11.111 //sample coordinates
1: 11.111 //sample coordinates
id: 2
name: "Jason"
location: Object
type: "Point",
coordinates: Array
0: 22.222 //sample coordinates
1: 22.222 //sample coordinates
收藏餐厅
id: 1
name: "Burger King"
location: Object
type: "Point",
coordinates: Array
0: 11.111 //sample coordinates
1: 11.111 //sample coordinates
isOpen: true
id: 2
name: "McDonald's"
location: Object
type: "Point",
coordinates: Array
0: 22.222 //sample coordinates
1: 22.222 //sample coordinates
isOpen: true
id: 3
name: "Chick-fil-A"
location: Object
type: "Point",
coordinates: Array
0: 22.333 //sample coordinates
1: 22.333 //sample coordinates
isOpen: true
收集产品
id: 1
name: "Breakfast Whopper Jr."
price: "$1.29"
isAvailable: true
isApproved: true
createdAt: Tues Dec 01 2020 09:15:19 GMT+0800
updatedAt: Tues Dec 01 2020 09:15:19 GMT+0800
isArchived: false
shop: ObjectId('1')
id: 2
name: "Big Mac"
price: "$4.35"
isAvailable: true
isApproved: true
createdAt: Tues Dec 01 2020 09:15:19 GMT+0800
updatedAt: Tues Dec 01 2020 09:15:19 GMT+0800
isArchived: false
shop: ObjectId('2')
id: 3
name: "Spicy Chicken Sandwich"
price: "$3.29"
isAvailable: true
isApproved: true
createdAt: Tues Dec 01 2020 09:15:19 GMT+0800
updatedAt: Tues Dec 01 2020 09:15:19 GMT+0800
isArchived: false
restaurant: ObjectId('3')
输出:如果Robert在坐标[22.222,22.222]中。罗伯特将看到餐厅McDonald's和Chick-fil-A,因为isOpen:true。由于isAvailable,isApproved:true和isArchived:false,请显示其产品“巨无霸”和“辣鸡肉三明治”。
没有答案,只是一些想法,你应该评估自己。以下管道:
isApproved:true, isAvailable:true, isArchived:true
因此,它假设并建议使用此索引:db.products.createIndex({
isAvailable: 1, isApproved: 1, isArchived: 1
})
foreignField:_id
使用索引就不需要索引,否则,我将在该字段上创建索引。isOpen:true
会很慢,但是如果可以的话,稍后会提高性能。pipeline
在$lookup
能够帮助实现更好的性能,添加此指数(恕我直言)db.restaurants.createIndex({ _id: 1, isOpen: 1 })
location
进入,是因为我们需要该领域db.products.aggregate([
{
$match: {
"isApproved": true,
"isAvailable": true,
"isArchived": false
}
},
{
$lookup: {
from: "restaurants",
foreignField: "_id",
localField: "restaurant",
as: "restaurant"
}
},
{
$match: {
"restaurant.isOpen": true
}
},
{
$project: {
"restaurant.isOpen": 1,
//"isApproved": 1,
//"isAvailable": 1,
//"isArchived": 1,
"name": 1,
"restaurant.location": 1
}
},
{
$match: {
"restaurant.location": {
$geoWithin: {
$centerSphere: [
[
22.222,
22.222
],
5/6378.1]
}
}
}}
])
我必须说我不是专家,所以你需要测试和改进。另外,请仅包含JSON格式的文档,以便我们立即进行测试。我必须手动进行LIVE VERSION。
(同样要记住,不是那么有用,但快速且完善的东西比一个非常复杂的应用程序最好。再次,你将了解它的工作原理,而且我也不是专家。)
嗨,@ Minsky对不起,您的回复很晚。它并没有让我回到附近的餐馆。它给我返回一个空数组。
太好了,不用客气