使用MongoDB以百分比形式获取匹配属性的百分比
我有一个用例,我需要输入一些属性列表,这些属性在mongodb中提供搜索结果,将90%的属性与所有数据相匹配。 例如: 我有这样的数据使用MongoDB以百分比形式获取匹配属性的百分比,mongodb,mongodb-query,Mongodb,Mongodb Query,我有一个用例,我需要输入一些属性列表,这些属性在mongodb中提供搜索结果,将90%的属性与所有数据相匹配。 例如: 我有这样的数据 [{ id: 1, properties: { 'property1': 'value1', 'property2': 'value2', 'property3': 'value3', 'property4': 'value4', 'property5': 'valu
[{
id: 1,
properties: {
'property1': 'value1',
'property2': 'value2',
'property3': 'value3',
'property4': 'value4',
'property5': 'value5'
}
},
{
id: 2,
properties: {
'property1': 'value1',
'property2': 'value2',
'property6': 'value6',
'property7': 'value7',
'property8': 'value8',
'property9': 'value9'
}
},
{
id: 3,
properties: {
'property9': 'value9'
}
}]
我想搜索两个属性,我正在寻找至少50%的匹配项,即至少1个属性应与两个输入中的任何一个匹配
输入查询
find
{
'property3', 'value3',
'property7', 'value7'
}
根据上述输入,它与数据库中3个数据中的2个数据匹配。
使用MongoDB是否可以进行写查询?这里有一些东西可以让您继续使用(不过您需要更新版本的MongoDB,至少是v3.4.4): 如果您只是在寻找匹配的文档,而不太关心66%的数字,那么这应该是可行的(未经测试,因为我正在路上)
这里有一些东西可以让您继续使用(不过您需要更新版本的MongoDB,至少是v3.4.4): 如果您只是在寻找匹配的文档,而不太关心66%的数字,那么这应该是可行的(未经测试,因为我正在路上)
您总是要搜索有限数量的属性(或常量2属性),还是这是动态的?如果它是一个静态的2,比如在你的例子中,你可以简单地使用$编写一个查询,或者…肯定是动态的,最多可以输入30个属性。你使用的是哪个版本的MongoDB?MongoDB 3.6.2 Community你总是要搜索有限数量的属性(或常量2属性)还是动态的?如果它是一个静态的2,就像你的例子中一样,你可以简单地用$or写一个查询,或者…肯定是动态的,最多可以输入30个属性。你使用的是哪个版本的MongoDB?MongoDB 3.6.2 Community谢谢你的帮助。它给出了匹配的百分比。是否可以将此查询转换为检索匹配的记录?对不起,我是Mongodby的初学者。你需要准确地告诉我你想要什么形状的记录。从示例中,它与三分之二的记录匹配。因此,您的查询提供了66%的匹配百分比。效果很好。但是,我想知道它匹配的记录是什么。在这个例子中,我可以说,它与文档{id:1,…..}和{id:2,…..}@dnickless:So匹配,如果我们在javascript数组对象中使用这个问题。我们怎么做到的?@NguyenTungs:我不明白你到底在问什么。请在SO上发布一个新问题,将会有回复!谢谢你的帮助。它给出了匹配的百分比。是否可以将此查询转换为检索匹配的记录?对不起,我是Mongodby的初学者。你需要准确地告诉我你想要什么形状的记录。从示例中,它与三分之二的记录匹配。因此,您的查询提供了66%的匹配百分比。效果很好。但是,我想知道它匹配的记录是什么。在这个例子中,我可以说,它与文档{id:1,…..}和{id:2,…..}@dnickless:So匹配,如果我们在javascript数组对象中使用这个问题。我们怎么做到的?@NguyenTungs:我不明白你到底在问什么。请在SO上发布一个新问题,将会有回复!
db.collection.aggregate({
$addFields: { // we add a helper field
"propertiesAsArray": { // called "propertiesAsArray"
$objectToArray: "$properties" // which will be the array representation of the "properties" field
}
}
}, {
$addFields: {
"matchRatio": { // the value we are looking for is...
$divide: [ { // ...the ratio between...
$size: { // ...the number of items...
$filter: {
"input": "$propertiesAsArray", // ...in our magic property array...
"as": "this",
"cond": { // ...that match any of our conditions...
$or: [
{ $eq: [ "$$this", { "k": "property3", "v": "value3" } ] },
{ $eq: [ "$$this", { "k": "property7", "v": "value7" } ] },
// ...of which we could have any number...
]
}
}
}
}, 2 ] // ...and the number of properties in your query
}
}
}, {
$facet: { // create two separate stages
"totalNumberOfDocs": [{
$count: "count" // one just calculates the total number of documents
}],
matchingDocs: [{ // and the second stage first filters out the non-matching documents
$match: {
"matchRatio": { $gte: 0.50 } // we only want documents with a match ratio >= 50%
}
}, {
$count: "count" // and then counts the remaining ones
}]
}
}, {
$project: { // final calculation of the ratio ("2 out of 3" in your example --> 66%)
"percentage": {
$divide: [
{ $arrayElemAt: [ "$matchingDocs.count", 0 ] },
{ $arrayElemAt: [ "$totalNumberOfDocs.count", 0 ] }
]
}
}
})
db.collection.aggregate({
$addFields: { // we add a helper field
"propertiesAsArray": { // called "propertiesAsArray"
$objectToArray: "$properties" // which will be the array representation of the "properties" field
}
}
}, {
$addFields: {
"matchRatio": { // the value we are looking for is...
$divide: [ { // ...the ratio between...
$size: { // ...the number of items...
$filter: {
"input": "$propertiesAsArray", // ...in our magic property array...
"as": "this",
"cond": { // ...that match any of our conditions...
$or: [
{ $eq: [ "$$this", { "k": "property3", "v": "value3" } ] },
{ $eq: [ "$$this", { "k": "property7", "v": "value7" } ] },
// ...of which we could have any number...
]
}
}
}
}, 2 ] // ...and the number of properties in your query
}
}
}, {
$match: {
"matchRatio": { $gte: 0.50 } // we only want documents with a match ratio >= 50%
}
})