【问题标题】:How to create index in mongodb with pymongo如何使用 pymongo 在 mongodb 中创建索引
【发布时间】:2018-08-17 12:17:19
【问题描述】:

我使用scrapy爬取数据并将其保存到mongodb,我想将2dsphere索引保存在mongodb中。

这是我的带有 scrapy 的 pipelines.py 文件

from pymongo import MongoClient
from scrapy.conf import settings

class MongoDBPipeline(object):

    global theaters
    theaters = []

    def __init__(self):
        connection = MongoClient(
            settings['MONGODB_SERVER'],
            settings['MONGODB_PORT'])
        self.db = connection[settings['MONGODB_DB']]
        self.collection = self.db[settings['MONGODB_COLLECTION']]

    def open_spider(self, spider):
        print 'Pipelines => open_spider =>'

    def process_item(self, item, spider):

        global theaters
        # get the class item name to be collection name
        self.collection = self.db[type(item).__name__.replace('_Item','')]

        if  item['theater'] not in theaters:
            print 'remove=>',item['theater']
            theaters.append(item['theater'])
            self.collection.remove({'theater': item['theater']})

        # insert the collection name that is from class object item
        self.collection.insert(dict(item))
        # Here is what i try to create 2dsphere index
        self.collection.create_index({"location": "2dsphere"})

        return item

当我使用self.collection.create_index({"location": "2dsphere"})

显示错误TypeError: if no direction is specified, key_or_list must be an instance of list

如果我尝试

self.collection.create_index([('location', "2dsphere")], name='search_index', default_language='english')

没有错误了,但是我的mongodb在location下仍然没有任何索引。

我认为我遵循 GeoJson 格式。

当我使用 scrapy 时,有什么方法可以在 mongodb 中保存 2dsphere 索引?或者我应该像照片结构一样保存数据并通过另一个服务器文件保存索引(如nodejs

任何帮助将不胜感激。提前致谢。

根据Adam Harrison回复,我尝试将我的mongodb名称location更改为geometry

比在我的 pipelines.py 文件中添加代码 import pymongo

并使用self.collection.create_index([("geometry", pymongo.GEOSPHERE)])

没有任何错误但仍然找不到geometry下的索引

【问题讨论】:

  • 他的问题是如何在 pymongo 中使用2dsphere 索引而不是如何在 pymongo 中保存2dsphere
  • 检查答案,它解决了如何指定2dsphere索引。
  • 试试collection.create_index([("geometry", pymongo.GEOSPHERE)])。取自票 bro-grammer 链接。请参阅api.mongodb.com/python/current/api/pymongo/collection.html 了解更多信息
  • 感谢您的回复,我添加 import pymongo 并将密钥名称 location 更改为 geometry 然后我使用 self.collection.create_index([("geometry", pymongo.GEOSPHERE)]) 。我的 mongodb 上仍然没有错误信息和索引。

标签: python node.js mongodb scrapy 2dsphere


【解决方案1】:

对我来说,有必要使用 ItemAdapter 将 Item 参数转换为列表。这样我就可以查询数据库了。

from itemadapter import ItemAdapter, adapter
import pymongo
from scrapy.exceptions import DropItem

collection_name = 'myCollection'
    
    def __init__(self, mongo_uri, mongo_db):
        self.mongo_uri = mongo_uri
        self.mongo_db = mongo_db
    @classmethod
    def from_crawler(cls, crawler):
        return cls(
            mongo_uri=crawler.settings.get('MONGO_URI'),
            mongo_db=crawler.settings.get('MONGO_DATABASE', 'items')
        )

def open_spider(self, spider):
    self.client = pymongo.MongoClient(self.mongo_uri)
    self.db = self.client[self.mongo_db]

def close_spider(self, spider):
    self.client.close()

process_item 函数:

def process_item(self, item, spider):
    adapter = ItemAdapter(item)
    if self.db[self.collection_name].find_one({'id':adapter['id']}) != None:
        dado = self.db[self.collection_name].find_one_and_update({'id':adapter['id']})
        ## ----> raise DropItem(f"Duplicate item found: {item!r}") <------
        print(f"Duplicate item found: {dado!r}")
    else:
        self.db[self.collection_name].insert_one(ItemAdapter(item).asdict())
    return item

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-08-20
    • 2016-02-06
    • 2013-06-07
    • 2014-10-21
    • 1970-01-01
    • 1970-01-01
    • 2018-03-14
    相关资源
    最近更新 更多