principales - ¿Es posible desarrollar un poderoso motor de búsqueda web usando Erlang, Mnesia & Yaws?
motores de busqueda mas utilizados (4)
En el contrib ''rdbms'' , hay una implementación del algoritmo Porter Stemming. Nunca se integró a ''rdbms'', por lo que básicamente se queda ahí. Lo hemos usado internamente, y funcionó bastante bien, al menos para los conjuntos de datos que no eran grandes (no lo he probado en grandes volúmenes de datos).
Los módulos relevantes son:
rdbms_wsearch.erl
rdbms_wsearch_idx.erl
rdbms_wsearch_porter.erl
Luego está, por supuesto, el marco Disco Map-Reduce .
Ya sea que puedas o no puedas hacer el motor más rápido, no podría decirlo. ¿Hay un mercado para un motor de búsqueda más rápido ? Nunca he tenido problemas con la velocidad de, por ejemplo, Google. Pero me interesaría un servicio de búsqueda que aumentara mis posibilidades de encontrar buenas respuestas a mis preguntas.
Estoy pensando en desarrollar un motor de búsqueda web usando Erlang, Mnesia & Yaws. ¿Es posible crear un motor de búsqueda web poderoso y rápido usando este software? ¿Qué necesitará para lograr esto y cómo empiezo?
Yo recomendaría CouchDB en lugar de Mnesia.
- Mnesia no tiene Map-Reduce, CouchDB sí (corrección - ver comentarios)
- Mnesia está tipada estáticamente, CouchDB es una base de datos de documentos (y las páginas son documentos, es decir, un mejor ajuste al modelo de información en mi opinión)
- Mnesia está destinado principalmente a ser una base de datos residente en memoria
YAWS es bastante bueno. También deberías considerar MochiWeb.
No te equivocarás con Erlang
Erlang puede hacer el rastreador web más poderoso hoy en día. Déjame guiarte por mi simple rastreador.
Paso 1. Creo un módulo de paralelismo simple, que llamo mapreduce
-module(mapreduce).
-export([compute/2]).
%%=====================================================================
%% usage example
%% Module = string
%% Function = tokens
%% List_of_arg_lists = [["file/r/nfile","/r/n"],["muzaaya_joshua","_"]]
%% Ans = [["file","file"],["muzaaya","joshua"]]
%% Job being done by two processes
%% i.e no. of processes spawned = length(List_of_arg_lists)
compute({Module,Function},List_of_arg_lists)->
S = self(),
Ref = erlang:make_ref(),
PJob = fun(Arg_list) -> erlang:apply(Module,Function,Arg_list) end,
Spawn_job = fun(Arg_list) ->
spawn(fun() -> execute(S,Ref,PJob,Arg_list) end)
end,
lists:foreach(Spawn_job,List_of_arg_lists),
gather(length(List_of_arg_lists),Ref,[]).
gather(0, _, L) -> L;
gather(N, Ref, L) ->
receive
{Ref,{''EXIT'',_}} -> gather(N-1,Ref,L);
{Ref, Result} -> gather(N-1, Ref, [Result|L])
end.
execute(Parent,Ref,Fun,Arg)->
Parent ! {Ref,(catch Fun(Arg))}.
Paso 2. El cliente HTTP
Uno normalmente usaría el inets httpc module
integrado en erlang o ibrowse
. Sin embargo, para la administración de memoria y la velocidad (haciendo que la huella de memoria sea lo más baja posible), un buen programador de erlang elegiría usar curl
. Al aplicar el os:cmd/1
que toma esa línea de comando curl, se obtendría la salida directamente en la función de llamada erlang. Aún así, es mejor hacer que Curl arroje sus salidas en archivos y luego nuestra aplicación tiene otro hilo (proceso) que lee y analiza estos archivos
Command: curl "http://www.erlang.org" -o "/downloaded_sites/erlang/file1.html"
In Erlang
os:cmd("curl /"http://www.erlang.org/" -o /"/downloaded_sites/erlang/file1.html/"").
Entonces puedes generar muchos procesos. Recuerda escaparse tanto de la URL como de la ruta del archivo de salida al ejecutar ese comando. Por otro lado, hay un proceso cuyo trabajo es observar el directorio de las páginas descargadas. Estas páginas las lee y las analiza, luego puede eliminarlas después de analizarlas o guardarlas en una ubicación diferente o incluso mejor, archivarlas usando el zip module
folder_check()-> spawn(fun() -> check_and_report() end), ok. -define(CHECK_INTERVAL,5). check_and_report()-> %% avoid using %% filelib:list_dir/1 %% if files are many, memory !!! case os:cmd("ls | wc -l") of "0/n" -> ok; "0" -> ok; _ -> ?MODULE:new_files_found() end, sleep(timer:seconds(?CHECK_INTERVAL)), %% keep checking check_and_report(). new_files_found()-> %% inform our parser to pick files %% once it parses a file, it has to %% delete it or save it some %% where else gen_server:cast(?MODULE,files_detected).
Paso 3. El analizador html.
Es mejor utilizar mochiweb''s html parser and XPATH
este mochiweb''s html parser and XPATH
. Esto te ayudará a analizar y obtener todas tus etiquetas HTML favoritas, extraer los contenidos y luego ir por buen camino. Los ejemplos a continuación, me centré solo en las Keywords
, la description
y el title
en el marcado
Módulo de pruebas en shell ... ¡resultados asombrosos!
2> spider_bot:parse_url("http://erlang.org").
[[[],[],
{"keywords",
"erlang, functional, programming, fault-tolerant, distributed, multi-platform, portable, software, multi-core, smp, concurrency "},
{"description","open-source erlang official website"}],
{title,"erlang programming language, official website"}]
3> spider_bot:parse_url("http://facebook.com").
[[{"description",
" facebook is a social utility that connects people with friends and others who work, study and live around them. people use facebook to keep up with friends, upload an unlimited number of photos, post links
and videos, and learn more about the people they meet."},
{"robots","noodp,noydir"},
[],[],[],[]],
{title,"incompatible browser | facebook"}]
4> spider_bot:parse_url("http://python.org").
[[{"description",
" home page for python, an interpreted, interactive, object-oriented, extensible/n programming language. it provides an extraordinary combination of clarity and/n versatility, and is free and
comprehensively ported."},
{"keywords",
"python programming language object oriented web free source"},
[]],
{title,"python programming language – official website"}]
5> spider_bot:parse_url("http://www.house.gov/"). [[[],[],[], {"description", "home page of the united states house of representatives"}, {"description", "home page of the united states house of representatives"}, [],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[],[], [],[],[]|...], {title,"united states house of representatives, 111th congress, 2nd session"}]
Ahora puede darse cuenta de que podemos indexar las páginas con sus palabras clave, además de un buen calendario de revisiones de páginas. Otro desafío fue cómo hacer un rastreador (algo que se moverá por toda la web, de un dominio a otro), pero ese es fácil. Es posible al analizar un archivo Html para las etiquetas href. Cree el analizador HTML para extraer todas las etiquetas href y, a continuación, puede necesitar algunas expresiones regulares aquí y allá para obtener los enlaces directamente bajo un dominio determinado.
Ejecutando el rastreador
7> spider_connect:conn2("http://erlang.org").
Links: ["http://www.erlang.org/index.html",
"http://www.erlang.org/rss.xml",
"http://erlang.org/index.html","http://erlang.org/about.html",
"http://erlang.org/download.html",
"http://erlang.org/links.html","http://erlang.org/faq.html",
"http://erlang.org/eep.html",
"http://erlang.org/starting.html",
"http://erlang.org/doc.html",
"http://erlang.org/examples.html",
"http://erlang.org/user.html",
"http://erlang.org/mirrors.html",
"http://www.pragprog.com/titles/jaerlang/programming-erlang",
"http://oreilly.com/catalog/9780596518189",
"http://erlang.org/download.html",
"http://www.erlang-factory.com/conference/ErlangUserConference2010/speakers",
"http://erlang.org/download/otp_src_R14B.readme",
"http://erlang.org/download.html",
"https://www.erlang-factory.com/conference/ErlangUserConference2010/register",
"http://www.erlang-factory.com/conference/ErlangUserConference2010/submit_talk",
"http://www.erlang.org/workshop/2010/",
"http://erlangcamp.com","http://manning.com/logan",
"http://erlangcamp.com","http://twitter.com/erlangcamp",
"http://www.erlang-factory.com/conference/London2010/speakers/joearmstrong/",
"http://www.erlang-factory.com/conference/London2010/speakers/RobertVirding/",
"http://www.erlang-factory.com/conference/London2010/speakers/MartinOdersky/",
"http://www.erlang-factory.com/",
"http://erlang.org/download/otp_src_R14A.readme",
"http://erlang.org/download.html",
"http://www.erlang-factory.com/conference/London2010",
"http://github.com/erlang/otp",
"http://erlang.org/download.html",
"http://erlang.org/doc/man/erl_nif.html",
"http://github.com/erlang/otp",
"http://erlang.org/download.html",
"http://www.erlang-factory.com/conference/ErlangUserConference2009",
"http://erlang.org/doc/efficiency_guide/drivers.html",
"http://erlang.org/download.html",
"http://erlang.org/workshop/2009/index.html",
"http://groups.google.com/group/erlang-programming",
"http://www.erlang.org/eeps/eep-0010.html",
"http://erlang.org/download/otp_src_R13B.readme",
"http://erlang.org/download.html",
"http://oreilly.com/catalog/9780596518189",
"http://www.erlang-factory.com",
"http://www.manning.com/logan",
"http://www.erlang.se/euc/08/index.html",
"http://erlang.org/download/otp_src_R12B-5.readme",
"http://erlang.org/download.html",
"http://erlang.org/workshop/2008/index.html",
"http://www.erlang-exchange.com",
"http://erlang.org/doc/highlights.html",
"http://www.erlang.se/euc/07/",
"http://www.erlang.se/workshop/2007/",
"http://erlang.org/eep.html",
"http://erlang.org/download/otp_src_R11B-5.readme",
"http://pragmaticprogrammer.com/titles/jaerlang/index.html",
"http://erlang.org/project/test_server",
"http://erlang.org/download-stats/",
"http://erlang.org/user.html#smtp_client-1.0",
"http://erlang.org/user.html#xmlrpc-1.13",
"http://erlang.org/EPLICENSE",
"http://erlang.org/project/megaco/",
"http://www.erlang-consulting.com/training_fs.html",
"http://erlang.org/old_news.html"]
ok
Almacenamiento: es uno de los conceptos más importantes para un motor de búsqueda. Es un gran error almacenar los datos del motor de búsqueda en un RDBMS como MySQL, Oracle, MS SQL, etc. Estos sistemas son completamente complejos y las aplicaciones que interactúan con ellos emplean algoritmos heurísticos. Esto nos lleva a Key-Value Stores , de las cuales las dos mejores son Couch Base Server
y Riak
. Estos son excelentes sistemas de archivos en la nube. Otro parámetro importante es el almacenamiento en caché. El almacenamiento en caché se logra utilizando, por ejemplo, Memcached
, del cual los otros dos sistemas de almacenamiento mencionados anteriormente tienen soporte. Los sistemas de almacenamiento para los motores de búsqueda deben ser schemaless DBMS
, que se centre en la Availability rather than Consistency
. Lea más sobre los motores de búsqueda desde aquí: http://en.wikipedia.org/wiki/Web_search_engine