11

请查看以下代码行和结果:

import pymongo

d1 = {'p': 0.5, 'theta': 100, 'sigma': 20}
d2 = {'theta': 100, 'sigma': 20, 'p': 0.5}

I get the following results:

d1 == d2 // Returns True

collectn.find({'goods.H': d1}).count() // Returns 33

collectn.find({'goods.H': d2}).count() // Returns 2

其中,collectn是一个 Mongodb 集合对象。

是否有设置或查询方法,以便我为上述两个查询获得相同的结果?

他们本质上使用的是同一个字典(在存在的意义上d1 == d2True。我正在尝试执行以下操作:在将记录插入数据库之前,我检查是否已经存在具有正在添加的确切值组合的记录。如果是这样,那么我不想创造新的记录。但是由于上面显示的行为,即使它确实存在并且将重复记录添加到数据库中(当然,具有不同的_id但所有其他值都是相同的,我更喜欢),也有可能得到该记录不存在没有那个)。

预先感谢您的帮助。

4

4 回答 4

6

您遇到的问题在此处的 mongodb 文档中进行了说明。它还与 Python 字典是无序的,而 MongoDB 对象是有序的 BSON 对象这一事实有关。

相关的报价是,

如果子文档与指定的子文档(包括字段顺序)完全匹配,则子文档内的相等匹配选择文档。

我认为如果将所有三个属性都视为主对象的子属性,而不是作为子对象的一个​​属性集合,我认为你可能会更好。这样子对象的排序就不会被 python 解释器强加到查询中。

例如...

d1 = {'goods.H.p': 0.5, 'goods.H.theta': 100, 'goods.H.sigma': 20}
d2 = {'goods.H.theta': 100, 'goods.H.sigma': 20, 'goods.H.p': 0.5}

collectn.find(d1).count()
collectn.find(d2).count()

...可能会产生更一致的结果。

最后,一种改变更少代码的方法:

collectn.find({'goods.H.' + k:v for k,v in d1.items()})
collectn.find({'goods.H.' + k:v for k,v in d2.items()})
于 2013-01-14T19:53:39.487 回答
1

我只能想到两件事要做:

  1. 将您的查询构造为:collectn.find({'goods.H.p':0.5, 'goods.H.theta':100, 'goods.H.sigma':20}).count()。这将找到正确数量的文件......

  2. 重组你的数据->如果你看一下MongoDB:索引顺序和查询顺序必须匹配?你会希望你可以在 p,sigma,theta 上建立索引,这样当在查询中,任何顺序的术语都会提供正确的结果。在我的简短测试中(我不是专家),我无法以一种与您当前的结构产生相同效果的方式进行索引。

于 2013-01-14T19:54:24.153 回答
0

我认为您正在寻找$where 运算符

这适用于节点:

var myCursor = coll.find({$where: function () {return obj.goods.H == d1}});
myCursor.count(function (err, myCount) {console.log(myCount)});

在 Python 中,我相信您需要传入BSON 代码对象

文档警告说,$where 运算符应该作为最后的手段使用,因为它会带来性能损失,并且不能使用索引。

似乎值得建立子属性的排序,并在可能的情况下在插入或作为后期处理时强制执行。

于 2013-01-14T20:24:51.097 回答
0

我认为您的问题在 mongodb doc 中提到:

该字段必须与子文档完全匹配,包括 order....

在这里查看文档。有子文档的例子。

子文档中的字段必须与查询中的字段顺序相同才能匹配。

于 2013-01-14T20:03:02.107 回答