按匹配元素数量顺序查询MongoDB中包含的数组元素

时间:2014-01-19 00:10:54

标签: mongodb sorting nosql

我有一个MongoDB,其中包含一系列文档:

{


_id: ObjectId("5222769532fed3037d000049"),


cat_list: { "52226a8932fed36c3000007e": 1   },   
feature_list: {
    "52227433abb03fa34b0000fa": 0.2,
    "52236117099c8924c500004a": 0.2,
    "52236236c71890c199000054": 0.2,
    "522374d2842e497d2c00000c": 0.2,
     "52237e3b842e493760000021": 0.2   },   
title: "blah"

}

现在我基本上想找到与feature_list内的密钥提供的一组密钥匹配的文档。为此,我想我将使用某种形式的[,],但是我不确定如何使用键:值列表。 (它是一样的吗?)

其次,我想按降序频率排序结果(如果我可以在mongodb中执行此操作而无需在我的服务器端代码中执行此操作)。因此,如果我查询"52227433abb03fa34b0000fa" OR "52236117099c8924c500004a" OR "52236236c71890c199000054",我的结果集将包含所有具有feature_list的文档,其中包含OR列表中的一个或多个,并且首先是匹配量最大的文档,然后是接下来的频率等等。

1 个答案:

答案 0 :(得分:2)

要使用至少一个具有给定值的字段查找所有这些文档,您可以使用此查询:

db.aggr.find({$or: [
{ "feature_list.52227433abb03fa34b0000fa" : { $exists: true } },
{ "feature_list.52236117099c8924c500004a" : { $exists: true } },
{ "feature_list.52236236c71890c199000054" : { $exists: true } } 
]});

找到你的文件:

{
    "_id" : ObjectId("5222769532fed3037d000049"),
    "cat_list" : {
        "52226a8932fed36c3000007e" : 1
    },
    "feature_list" : {
        "52227433abb03fa34b0000fa" : 0.2,
        "52236117099c8924c500004a" : 0.2,
        "52236236c71890c199000054" : 0.2,
        "522374d2842e497d2c00000c" : 0.2,
        "52237e3b842e493760000021" : 0.2
    },
    "title" : "blah"
}

但你不能按照你想要的方式对它进行排序,因为没有任何可排序的东西。我正在考虑按所有这些搜索字段进行排序,如果只搜索一个字段,它会起作用,因为缺少的字段会有lowest value。但是,在这种情况下,对于多个字段,sort中字段的顺序很重要,这个技巧不起作用。

什么也行不通的是尝试按整个子文档排序,即.sort({"feature_list" : -1})因为它没有给出任何有意义的排序。

所以在这一点上获得这些结果的唯一方法是使用聚合框架,多个查询(例如3个),或者在代码中执行此操作。

我很确定我可以写一个聚合框架查询来做到这一点,但首先你会受到单个文档大小(32Mb)中可以容纳的结果数量的限制。如果你只返回id,那就更好了。其次,它实际上可能不是那么有效。最后,您可能需要考虑重新设计架构,因为它非常传统。这样查询会很困难,也很低效。

修改

可以像这样重新设计架构:

{ ...,
  feature_list: [
    {fid: "52227433abb03fa34b0000fa", weight: 0.2},
    {fid: "52236117099c8924c500004a", weight: 0.2}
  ]
}

这仍然无助于使用常规查询进行排序,但是查找数据会快得多,因为Mongo不使用$exists的索引,但会在这个新架构中使用索引(如果存在),其中字段变为数据。没有办法按照数组中匹配元素的数量对Mongo进行排序。

您可以使用聚合框架而不是常规查询以非常类似的方式获取数据: In MongoDB search in an array and sort by number of matches 问题是您只能使用聚合框架获得尽可能多的结果。为了充分利用它,您可以在最后的步骤中仅投影文档的_id。

使用聚合框架的替代方法是在找到结果后对代码中的数据进行排序。在任何一种情况下,由于索引,模式重新设计似乎都是有益的。