Php mongodb中匹配的或条件的百分比
我得到了以下格式的数据Php mongodb中匹配的或条件的百分比,php,mongodb,mongodb-query,aggregation-framework,mongodb-php,Php,Mongodb,Mongodb Query,Aggregation Framework,Mongodb Php,我得到了以下格式的数据 { "_id" : ObjectId("534fd4662d22a05415000000"), "product_id" : "50862224", "ean" : "8808992479390", "brand" : "LG", "model" : "37LH3000", "features" : [{ { "key" : "Screen Format", "value" : "16:9", }, {
{
"_id" : ObjectId("534fd4662d22a05415000000"),
"product_id" : "50862224",
"ean" : "8808992479390",
"brand" : "LG",
"model" : "37LH3000",
"features" : [{
{
"key" : "Screen Format",
"value" : "16:9",
}, {
"key" : "DVD Player / Recorder",
"value" : "No",
},
"key" : "Weight in kg",
"value" : "12.6",
}
... so on
]
}
我需要将一个产品的功能与其他产品的功能进行比较,并根据功能匹配的百分比将结果分为单独的类别(100%匹配,50-99%匹配)
我最初的想法是为每个特性准备一个带有or条件的动态查询,并用php进行百分比计算,但这意味着mongodb将返回我,即使是那些只有1个特性匹配的产品。我认为几乎所有类别的产品都可能有一些共同的特性,所以我担心我可能正在用php开发很多产品
我基本上有两个问题
我假设您希望将该系列的其余部分与给定产品进行比较,这是一个典型的聚合示例:
lookingat = db.products.findOne({product_id:'50862224'})
matches = db.products.aggregate([
{ $unwind: '$features' },
{ $match: { features: { $in: lookingat.features }}},
{ $group: { _id: '$product_id', matchedfeatures: { $sum:1 }}},
{ $sort: { matchedfeatures: -1 }},
{ $limit: 5 },
{ $project: { _id:0, product_id: '$_id',
pctmatch: { $multiply: [ '$matchedfeatures',
100/lookingat.features.length ]}
}}
])
从集合中具有6个功能的产品的角度简要介绍这一点,并将其与具有4个功能的目标产品(“lookingat”)进行比较,其中3个功能匹配:
我假设您希望将该系列的其余部分与给定产品进行比较,这是一个典型的聚合示例:
lookingat = db.products.findOne({product_id:'50862224'})
matches = db.products.aggregate([
{ $unwind: '$features' },
{ $match: { features: { $in: lookingat.features }}},
{ $group: { _id: '$product_id', matchedfeatures: { $sum:1 }}},
{ $sort: { matchedfeatures: -1 }},
{ $limit: 5 },
{ $project: { _id:0, product_id: '$_id',
pctmatch: { $multiply: [ '$matchedfeatures',
100/lookingat.features.length ]}
}}
])
从集合中具有6个功能的产品的角度简要介绍这一点,并将其与具有4个功能的目标产品(“lookingat”)进行比较,其中3个功能匹配:
您的解决方案应该是特定于MongoDB的,否则您将在客户端进行计算和可能的匹配,这对性能没有好处 当然,您真正想要的是一种在服务器端进行处理的方法:
db.products.aggregate([
//匹配符合条件的文档
{“$match”:{
“$or”:[
{
“特征”:{
“$elemMatch”:{
“键”:“屏幕格式”,
“值”:“16:9”
}
}
},
{
“特征”:{
“$elemMatch”:{
“键”:“重量(kg)”,
“值”:{“$gt”:“5”,“$lt”:“8”}
}
}
},
]
}},
//保留文档和功能阵列的副本
{“$project”:{
“_id”:{
“\u id”:“$\u id”,
“产品id”:“$product\U id”,
“ean”:“$ean”,
“品牌”:“$brand”,
“模型”:“$model”,
“功能”:“$features”
},
“特色”:1
}},
//展开阵列
{“$unwind”:“$features”},
//查找与条件匹配的实际元素
{“$match”:{
“$or”:[
{
“features.key”:“屏幕格式”,
“特征值”:“16:9”
},
{
“features.key”:“重量单位为kg”,
“features.value”:{“$gt”:“5”,“$lt”:“8”}
},
]
}},
//数一数那些匹配的元素
{“$组”:{
“\u id”:“$\u id”,
“计数”:{“$sum”:1}
}},
//恢复文档并将匹配的元素除以
//处于“或”状态的元素数
{“$project”:{
“\u id”:“$\u id.\u id”,
“产品id”:“$\u id.产品id”,
“ean”:“$\u id.ean”,
“品牌”:“$\u id.brand”,
“模型”:“$\u id.model”,
“功能”:“$\u id.features”,
“匹配”:{“$divide”:[“$count”,2]}
}},
//按匹配的百分比排序
{“$sort”:{“matched”:-1}
])
因此,当您知道要应用的$或
条件的“长度”时,您只需找出“features”数组中有多少元素与这些条件匹配。这就是管道中第二个$match的全部内容
一旦你有了这个计数,你只需除以作为你的$或
传入的条件数。我喜欢这里的美丽