MongoDB最匹配的属性

时间:2018-02-17 17:44:29

标签: mongodb mongoose mongodb-query aggregation-framework

我想在MongoDB中有一个Users集合,其架构如下所示:

{
    name: String,
    sport: String,
    favoriteColor: String
}

让我们说我传入了这样的值来匹配用户:

{ name: "Thomas", sport: "Tennis", favoriteColor:"blue" }

我想要做的是根据所有这些属性匹配用户。但是,如果没有用户回来,我想在这些属性上匹配用户:

{sport: "Tennis", favoriteColor:"blue" }

如果没有用户回来,我想在这个属性上匹配一个用户:

{ favoriteColor: "blue" }

是否可以在Mongo的一个查询中执行类似的操作?我看到Mongo中的$switch条件会匹配案例然后立即返回,但问题是我无法访问它在then块中检索到的文档。看起来你只能在那里写字符串。

有关如何完成我正在寻找的内容的任何建议?

执行多个User.find({...})查询是最好的(也是唯一的方法)吗?

5 个答案:

答案 0 :(得分:4)

这是使用MongoDB文本索引的好例子:

首先,您需要在这些字段上创建text索引:

db.users.ensureIndex({ name: "text", sport: "text", favoriteColor: "text" });

然后,您可以使用" $text"搜索最佳匹配。由数字限制显示:

db.users.find( { $text: { $search: "Tennis blue Thomas" } } ).limit(10)

答案 1 :(得分:2)

尝试在汇总管道中为所有具有权重的文档添加排名,并将排名$sort相加,以获得最匹配的文档

  1. 名称 - > 1
  2. sport - > 2
  3. favoriteColor - > 4
  4. 通过这样做匹配favoriteColor将始终具有更高的权重,然后运动和名称或两者的组合

    聚合管道

    db.col.aggregate([
        {$match : {
            $or : [
                {"name" : {$eq :"Thomas"}},
                {"sport" : {$eq : "Tennis"}},
                {"favoriteColor" : {$eq : "blue"}}
            ]
        }},
        {$addFields : {
            rank : {$sum : [
                {$cond : [{$eq : ["$name", "Thomas"]}, 1, 0]},
                {$cond : [{$eq : ["$sport", "Tennis"]}, 2, 0]},
                {$cond : [{$eq : ["$favoriteColor", "blue"]}, 4, 0]}
            ]}
        }},
        {$match : {rank :{$gt : 0}}},
        {$sort : {rank : -1}}
    ])
    

答案 2 :(得分:2)

希望此查询能满足您的要求条件,您可以在单个数据库命中中获得相关结果。只需在aggregate管道

中创建一个查询
db.collection.aggregate([
{$match : {
        $or : [
            {"name" : {$eq :"Thomas"}},
            {"sport" : {$eq : "Tennis"}},
            {"favoriteColor" : {$eq : "blue"}}
        ]
}},
 {$addFields : {
        rank : {$sum : [
            {$cond : [{$and:[{$eq : ["$name", "Thomas"]},{$eq : ["$sport", "Tennis"]},{$eq : ["$favoriteColor", "blue"]}]  }  , 1, 0]},
            {$cond : [{$and:[{$eq : ["$name", "Thomas"]},{$eq : ["$sport", "Tennis"]}]  }  , 2, 0]},
            {$cond : [{$and:[{$eq : ["$name", "Thomas"]}]  } , 3, 0]},
        ]}
}},

{$group:{
    _id:null,
    doc:{$push:'$$ROOT'},
    rank:{$max:'$rank'}
}},
{$unwind:'$doc'},
{$redact: {
    $cond: {
      if: { $eq: [ "$doc.rank", '$rank' ] },
      then: "$$KEEP",
      else: "$$PRUNE"
    }
  }},
  {
      $project:{
            name:'$doc.name',
            sport:'$doc.sport',
            favoriteColor:'$doc.favoriteColor',
    }}
])

答案 3 :(得分:2)

只需在mongoDB聚合管道中为TimePickerFragment.OnCompleteListener管道创建一个查询构建器,或者将其用于查找,创建JavaScript对象变量并动态构建查询。

$match

它将在动态基础上给出完全匹配的结果

答案 4 :(得分:1)

您是否尝试使用$orhttps://docs.mongodb.com/manual/reference/operator/query/or/

当我想检查是否存在用户名或电子邮件时,我使用了它。