我正在编写一个Web Crawler,现在它已经工作了,我想制作一个get_inverted_index函数。 因此,我有两个集合:词典和文档。在文档词典的每个文档中,我有一个名为words的数组,其中包含每个文档(页面)中每个单词的id和字体大小。我的下一步是迭代单词并查找具有每个特定单词的文档,但我看不到如何为此请求编写查询。我尝试了以下代码段:
k = {}
for word in self.lexicon.find():
s = set()
for page in self.documents.find({'words' : {'$in' : word['_id'}}):
但是这个查询无法正常工作。 例如,我的词典集合中的一个条目:
{
"_id": {
"$oid": "54723c55b59c44a167ed3424"
},
"word": "google"
}
我的文件集中的一个例子:
{
"_id": {
"$oid": "54723c54b59c44a167ed3423"
},
"url": "http://www.google.com",
"words": [
[
{
"$oid": "54723c55b59c44a167ed3424"
},
7
],
[
{
"$oid": "54723c55b59c44a167ed3425"
},
2
],
[
{
"$oid": "54723c55b59c44a167ed3428"
},
0
],
[
{
"$oid": "54723c55b59c44a167ed342b"
},
0
],
[
{
"$oid": "54723c56b59c44a167ed342e"
},
0
],
[
{
"$oid": "54723c5eb59c44a167ed3477"
},
0
]
]
}
@Edit
我也尝试使用正则表达式,但没有成功:(用于测试表达式)
for page in documents.find({'words' : [ObjectId('547244abb59c44a167ed4a84'), {"$regex": "*"}]}):
print page
另外
for page in documents.find({'words' : [{'$in' : ObjectId('547244abb59c44a167ed4a84')}, {'$regex': '*'}]}):
print page
答案 0 :(得分:1)
对于文档集合来说,这是一个非常不幸的架构选择。
你说你有一个名为words
的数组,其中包含每个文档中每个单词的id和字体大小。不幸的是,你有这个id和字体大小作为另一个数组。有意义的是将id和字体大小作为子文档中的命名字段。换句话说,你需要一个字典列表,而不是列表列表。
{ "_id": <id here>,
"url": "http://www.google.com",
"words": [
{ "id":<id>, "fs":7 },
{ "id":<id>, "fs":2 }
]
}
这样可以通过documents.find({"words.id":<id>})
查询进行查询。此外,如果您碰巧想要跟踪每个单词的其他内容,那么第二个数字意味着什么也不会是个谜。
虽然你可以设法做一个恰好返回你想要的模式的查询,但它实际上并不适合它所描述的内容。但是,如果 决定继续使用当前结构,则查询它的正确方法是
documents.find({'words':{'$elemMatch':{'0':word['_id']}}})
而不是使用double $ elemMatch,此语法专门查找其第一个元素与所讨论的_id匹配的数组元素。
答案 1 :(得分:0)
看起来您需要在更深层次上搜索文档集合。
截至目前,您正在搜索元素
{
"$oid": "54723c55b59c44a167ed3424"
}
文档集合的$ in运算符将其与列表元素进行比较,例如:
[
{
"$oid": "54723c55b59c44a167ed3424"
},
7
]
这显然不一样了。不幸的是我没有mongodb来测试任何东西,但也许这个技巧可以帮助你改善你的查询。
编辑: 找到关于类似问题的较早问题here,这可能会有所帮助。根据那篇文章,类似下面的作品:
for page in documents.find({'words':{$elemMatch:{$elemMatch:{$in:[word['_id']]}}}})