NeoTechnology был представлен на TechCrunch после поднятия раунда серии B , и он имеет запись на CrunchBase . Если вы внимательно посмотрите на CrunchBase, то заметите, что это график. Кто во что инвестировал, кто соинвестировал, каковы общие темы инвестирования между инвесторами, как компании связаны между собой членами совета директоров и т. Д. Это вопросы, которые мы можем задать для графика и которые хорошо подходят для графических баз данных.
Итак, давайте вернемся к этому. Этот проект и набор данных доступны на Github , но если вы хотите воспроизвести его самостоятельно, вам нужно зарегистрироваться на http://developer.crunchbase.com и получить ключ API. После того, как у вас есть один, вы можете взглянуть на возвращенный JSON, перейдя в IO Docs . Вот часть записи компании «нео-технологии».
{ "name": "Neo Technology", "permalink": "neo-technology", "crunchbase_url": "http://www.crunchbase.com/company/neo-technology", "homepage_url": "http://www.neotechnology.com", "blog_url": "", "blog_feed_url": "", "twitter_username": "", "category_code": "software", "number_of_employees": null, "founded_year": 2007, "founded_month": null, "founded_day": null, "deadpooled_year": null, "deadpooled_month": null, "deadpooled_day": null, "deadpooled_url": null, "tag_list": "graphs, open-soure-graphs, graph-systems, commercial-graphs, graph-database", "alias_list": "", "email_address": "", "phone_number": "", "description": "Graph Database", ...
Я не собираюсь отображать все CrunchBase, но я возьму несколько интересных вещей. Я импортирую компании, людей, финансовые организации и теги как Узлы, а также связи сотрудников, инвесторов, тегов и конкурентов как Отношения в Neo4j .
Я использую замечательный драгоценный камень CrunchBase от Tyler Cunnion . Я начинаю с получения всех сущностей, которые меня интересуют (например, это Люди):
all_people = Crunchbase::Person.all all_people.each do |ap| begin next unless ap.permalink file = "crunchbase/people/#{ap.permalink}" if File.exist?(file) person = Marshal::load(File.open(file, 'r')) else person = ap.entity File.open(file, 'wb') { |fp| fp.write(Marshal::dump(person)) } end people << {:name => "#{person.first_name || ""} #{person.last_name || ""}", :permalink => person.permalink, :crunchbase_url => person.crunchbase_url || "", :homepage_url => person.homepage_url || "", :overview => person.overview || "" } rescue Exception => e puts e.message end end
Я сохраняю JSON, возвращенный из CrunchBase API, в файл на случай, если что-то пойдет не так, и мне нужно перезапустить импорт. Neo4j не любит нулевые значения для свойств, поэтому на всякий случай я использую пустую строку, если значение не найдено.
Я буду использовать полнотекстовый индекс lucene, чтобы люди могли найти свою любимую компанию, человека, метку или финансовую организацию по постоянной ссылке, поэтому сначала создадим ее.
neo = Neography::Rest.new neo.create_node_index("node_index", "fulltext", "lucene")
Затем я буду создавать узлы для этих сущностей (при сохранении идентификатора узла, возвращенного в хеш):
people_nodes = {} people.each_slice(100) do |slice| commands = [] slice.each_with_index do |person, index| commands << [:create_unique_node, "node_index", "permalink", person[:permalink], person] end batch_results = neo.batch *commands batch_results.each do |result| people_nodes[result["body"]["data"]["permalink"]] = result["body"]["self"].split('/').last end end
Я использую Neo4j Rest Batch метод отправки 100 команд одновременно.
Затем я создаю отношения друг с другом. Например сотрудники компаний:
employees.each_slice(100) do |slice| commands = [] slice.each do |employee| commands << [:create_relationship, employee[:type], people_nodes[employee[:from]], company_nodes[employee[:to]], employee[:properties]] end batch_results = neo.batch *commands end
Для внешнего интерфейса мне нужны два основных метода. Один вернет все узлы и типы отношений, связанные с одним узлом:
cypher = "START me=node(#{params[:id]}) MATCH me -[r?]- related RETURN me, r, related" connections = neo.execute_query(cypher)["data"]
Второй запрос обрабатывает полнотекстовый поиск и форматирует выходные данные в хэш JSON, с которым JQuery Autocomplete может работать:
get '/search' do content_type :json neo = Neography::Rest.new cypher = "START me=node:node_index({query}) RETURN ID(me), me.name ORDER BY me.name LIMIT 15" query = "permalink:*#{params[:term]}* OR name:*#{params[:term]}*" neo.execute_query(cypher, {:query => query })["data"]. map{|x| { label: x[1], value: x[0] } }.to_json end
Обратите внимание, как я передаю весь запрос Lucene в качестве параметра? Это правильный способ сделать это. Я индексировал людей, компании и финансовые организации по постоянной ссылке, но индексировал теги по имени. Я использую предложение «ИЛИ», чтобы захватить их обоих.
Вы можете пропустить этап построения графика, если вы просто хотите использовать данные в том виде, в каком они существовали в день публикации этого блога, поскольку они доступны в репозитории github .
Вы можете клонировать репозиторий, создать приложение heroku и быстро его запустить.
git clone https://github.com/maxdemarzi/neo_crunch.git cd neo_crunch heroku apps:create heroku addons:add neo4j:try git push heroku master
Затем перейдите в свои приложения Heroku https://dashboard.heroku.com/apps/
Найдите свое приложение и перейдите в дополнение к Neo4j.
В разделе «Резервное копирование и восстановление» нажмите «Выбрать файл», найдите файл crunchbase.zip и нажмите «Отправить». Загрузка данных займет некоторое время, но как только вы сможете перейти к своему приложению и увидеть это:
Нажмите на изображение выше, чтобы увидеть его живую версию.