我用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
下的索引
最佳答案
对我来说,有必要使用 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
https://stackoverflow.com/questions/49185065/