Hi, i''m working on a project using Ferret for indexing it''s datas. I''m very happy with it but i need to code an extension to implement a .to_json method to TopDocs class, because ruby''s json implementation is really really slow... It''s my second (the first was the tutorial :/ ) ruby C extension, so i''m not really at ease with ruby C bindings, even with the C experience... Here is my problem : I would like to load each document from ids in my TopDoc object, to make the json string myself from that, but i don''t know how to load my documents from this class... it''s really weirdo to me actually :\ hope somebody can help ! Here is my code, situated in r_search.c : static VALUE frt_td_to_json(VALUE self) { int i; VALUE rhits = rb_funcall(self, id_hits, 0); VALUE rhit; const int len = RARRAY(rhits)->len; long pos; for (i = 0; i < len; i++) { rhit = RARRAY(rhits)->ptr[i]; pos = FIX2INT(rb_funcall(rhit, id_doc, 0)); // // HERE I WOUlD LIKE TO LOAD THE DOCUMENTS, ID IS THE GOOD DOC_ID.. // I WOULD LIKE TO GET THIS IN FACT (ruby): // doc_id = INDEX.search(''query'').hits.first // INDEX[doc_id].load <== THAT''S WHAT I WOULD LIKE TO GET ! // } rstr = rb_str_new2(str); free(str); return (argv[0]); } of course, i''ve bound the method to the good object etc... Hope somebody''ll help ! Thank you by advance, Jeremie ''ahFeel'' BORDIER -- Posted via http://www.ruby-forum.com/.
Damn, i''ve forgotten some debug / test code in the past :P of course, you don''t have to care about these lines :> rstr = rb_str_new2(str); > free(str); > return (argv[0]); > }> Thank you by advance, > Jeremie ''ahFeel'' BORDIER-- Posted via http://www.ruby-forum.com/.
David Balmain
2006-Oct-11 02:17 UTC
[Ferret-talk] Need help for coding an extension to ferret
On 10/11/06, ahFeel <ahfeel at rift.fr> wrote:> Hi, > > i''m working on a project using Ferret for indexing it''s datas. I''m very > happy with it but i need to code an extension to implement a .to_json > method to TopDocs class, because ruby''s json implementation is really > really slow... > > It''s my second (the first was the tutorial :/ ) ruby C extension, so i''m > not really at ease with ruby C bindings, even with the C experience... > > Here is my problem : > > I would like to load each document from ids in my TopDoc object, to make > the json string myself from that, but i don''t know how to load my > documents from this class... it''s really weirdo to me actually :\ hope > somebody can help ! > > Here is my code, situated in r_search.c : > > static VALUE > frt_td_to_json(VALUE self) > { > int i; > VALUE rhits = rb_funcall(self, id_hits, 0); > VALUE rhit; > const int len = RARRAY(rhits)->len; > long pos; > > for (i = 0; i < len; i++) > { > rhit = RARRAY(rhits)->ptr[i]; > pos = FIX2INT(rb_funcall(rhit, id_doc, 0)); > // > // HERE I WOUlD LIKE TO LOAD THE DOCUMENTS, ID IS THE GOOD DOC_ID.. > // I WOULD LIKE TO GET THIS IN FACT (ruby): > // doc_id = INDEX.search(''query'').hits.first > // INDEX[doc_id].load <== THAT''S WHAT I WOULD LIKE TO GET ! > // > } > rstr = rb_str_new2(str); > free(str); > return (argv[0]); > } > > of course, i''ve bound the method to the good object etc... > > Hope somebody''ll help ! > Thank you by advance, > Jeremie ''ahFeel'' BORDIER >The frt_td_to_s method is doing almost exactly this. Make sure you have have version 0.10.9 or later. Each TopDocs object has a reference to the searcher that created it. You can get a LazyDoc object for the searcher with the following call: LazyDoc *lazy_doc = sea->get_lazy_doc(searcher, id); By the way, id should be an int, not a long. To turn this into the lazy loading Hash object that you see in Ruby you use this method: VALUE frt_get_lazy_doc(LazyDoc *lazy_doc) The code for cLazyDoc is in r_index.c. Can I ask why you need to do this in the C code? It would seem to me to make a lot more sense to code this in Ruby but you probably have a good reason. Cheers, Dave
David Balmain wrote:> On 10/11/06, ahFeel <ahfeel at rift.fr> wrote: >> Here is my problem : >> { >> // >> >> of course, i''ve bound the method to the good object etc... >> >> Hope somebody''ll help ! >> Thank you by advance, >> Jeremie ''ahFeel'' BORDIER >> > > The frt_td_to_s method is doing almost exactly this. Make sure you > have have version 0.10.9 or later. Each TopDocs object has a reference > to the searcher that created it. You can get a LazyDoc object for the > searcher with the following call: > > LazyDoc *lazy_doc = sea->get_lazy_doc(searcher, id); > > By the way, id should be an int, not a long. To turn this into the > lazy loading Hash object that you see in Ruby you use this method: > > VALUE frt_get_lazy_doc(LazyDoc *lazy_doc) > > The code for cLazyDoc is in r_index.c. > > Can I ask why you need to do this in the C code? It would seem to me > to make a lot more sense to code this in Ruby but you probably have a > good reason. > > Cheers, > DaveHi dave ! First, thank you a lot for this anwser ! I''ve been looking and trying a lot of things such as sea = (Searcher *)DATA_PTR(self) to use the sea->get_lazy_doc function, but it returns a null pointer... maybe i did something wrong, i''ll retry, and be sure to have the last ferret release :) Concerning the reasons i''m doing this directly in C, it''s just because we need a really fast implementation.. I''m working with Florent Solt who you already knows, works on a big project using Ruby / Ferret. These datas are supposed to transit over a RPC protocol, and there will be a lot of queries, so we really need a fast to_json method :) Thank you again, Jeremie ''ahFeel'' BORDIER -- Posted via http://www.ruby-forum.com/.