3

我使用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 格式。

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

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

根据Adam Harrison回应,我尝试将我的 mongodb 名称更改locationgeometry

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

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

没有任何错误但仍然找不到下的索引geometry 在此处输入图像描述

4

1 回答 1

0

对我来说,有必要使用 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
于 2021-12-27T19:01:21.910 回答