首页 > 数据库 > > Xapian的内存索引-添加文档
Xapian::WritableDatabase db = Xapian::InMemory::open(); Xapian::Document doc; // 添加文档的,T表示字段名字,TERM内容为世界,position为1 doc.add_posting("T世界", 1); doc.add_posting("T体育", 2); doc.add_posting("T比赛", 3); // 添加doc的数据 doc.set_data("世界体育比赛"); // 添加doc的唯一term doc.add_boolean_term(K_DOC_UNIQUE_ID); // 采用replace_document,保证拥有K_DOC_UNIQUE_ID的文档在索引库中唯一 Xapian::docid innerId = db.replace_document(K_DOC_UNIQUE_ID, doc);
void Xapian::Document::Internal::need_terms() const { if (terms_here) { return; } if (database.get()) { Xapian::TermIterator t(database->open_term_list(did)); Xapian::TermIterator tend(NULL); for ( ; t != tend; ++t) { Xapian::PositionIterator p = t.positionlist_begin(); OmDocumentTerm term(t.get_wdf()); for ( ; p != t.positionlist_end(); ++p) { term.append_position(*p); } terms.insert(make_pair(*t, term)); } } termlist_size = terms.size(); terms_here = true; }
void Xapian::Document::Internal::add_posting(const string & tname, Xapian::termpos tpos, Xapian::termcount wdfinc) { need_terms(); positions_modified = true; std::map<std::string, OmDocumentTerm>::iterator i = terms.find(tname); if (i == terms.end()) { ++termlist_size; OmDocumentTerm newterm(wdfinc); newterm.append_position(tpos); terms.insert(make_pair(tname, newterm)); } else { // doc已经有这个term if (i->second.add_position(wdfinc, tpos)) { ++termlist_size; } } }
bool OmDocumentTerm::add_position(Xapian::termcount wdf_inc, Xapian::termpos tpos) { LOGCALL(DB, bool, "OmDocumentTerm::add_position", wdf_inc | tpos); if (rare(is_deleted())) { wdf = wdf_inc; split = ; positions.push_back(tpos); return true; } wdf += wdf_inc; // Optimise the common case of adding positions in ascending order. if (positions.empty()) { positions.push_back(tpos); return false; } if (tpos > positions.back()) { if (split) { // Check for duplicate before split. auto i = lower_bound(positions.cbegin(), positions.cbegin() + split, tpos); if (i != positions.cbegin() + split && *i == tpos) { return false; } } positions.push_back(tpos); return false; } if (tpos == positions.back()) { // Duplicate of last entry. return false; } if (split > ) { // We could merge in the new entry at the same time, but that seems to // make things much more complex for minor gains. merge(); } // Search for the position the term occurs at. Use binary chop to // search, since this is a sorted list. vector<Xapian::termpos>::iterator i = lower_bound(positions.begin(), positions.end(), tpos); if (i == positions.end() || *i != tpos) { auto new_split = positions.size(); if (sizeof(split) < sizeof(Xapian::termpos)) { if (rare(new_split > numeric_limits<decltype(split)>::max())) { // The split point would be beyond the size of the type used to // hold it, which is really unlikely if that type is 32-bit. // Just insert the old way in this case. positions.insert(i, tpos); return false; } } else { // This assertion should always be true because we shouldn't have // duplicate entries and the split point can't be after the final // entry. AssertRel(new_split, <=, numeric_limits<decltype(split)>::max()); } split = new_split; positions.push_back(tpos); } return false; }
void Xapian::Document::Internal::set_data(const string &data_) { data = data_; data_here = true; }
Xapian::docid WritableDatabase::replace_document(const std::string & unique_term, const Document & document) { LOGCALL(API, Xapian::docid, "WritableDatabase::replace_document", unique_term | document); if (unique_term.empty()) { throw InvalidArgumentError("Empty termnames are invalid"); } size_t n_dbs = internal.size(); if (rare(n_dbs == )) { no_subdatabases(); } if (n_dbs == 1) { RETURN(internal[]->replace_document(unique_term, document)); } Xapian::PostingIterator postit = postlist_begin(unique_term); // If no unique_term in the database, this is just an add_document(). if (postit == postlist_end(unique_term)) { // Which database will the next never used docid be in? Xapian::docid did = get_lastdocid() + 1; if (rare(did == )) { throw Xapian::DatabaseError("Run out of docids - you'll have to use copydatabase to eliminate any gaps before you can add more documents"); } size_t i = sub_db(did, n_dbs); RETURN(internal[i]->add_document(document)); } Xapian::docid retval = *postit; size_t i = sub_db(retval, n_dbs); internal[i]->replace_document(sub_docid(retval, n_dbs), document); // Delete any other occurrences of unique_term. while (++postit != postlist_end(unique_term)) { Xapian::docid did = *postit; i = sub_db(did, n_dbs); internal[i]->delete_document(sub_docid(did, n_dbs)); } return retval; }
Xapian::docid InMemoryDatabase::add_document(const Xapian::Document & document) { LOGCALL(DB, Xapian::docid, "InMemoryDatabase::add_document", document); if (closed) { InMemoryDatabase::throw_database_closed(); } Xapian::docid did = make_doc(document.get_data()); finish_add_doc(did, document); RETURN(did); }
Xapian::docid InMemoryDatabase::make_doc(const string & docdata) { termlists.push_back(InMemoryDoc(true)); doclengths.push_back(); doclists.push_back(docdata); AssertEqParanoid(termlists.size(), doclengths.size()); return termlists.size(); }
void InMemoryDatabase::finish_add_doc(Xapian::docid did, const Xapian::Document &document) { { std::map<Xapian::valueno, string> values; Xapian::ValueIterator k = document.values_begin(); for ( ; k != document.values_end(); ++k) { values.insert(make_pair(k.get_valueno(), *k)); LOGLINE(DB, "InMemoryDatabase::finish_add_doc(): adding value " << k.get_valueno() << " -> " << *k); } add_values(did, values); } InMemoryDoc doc(true); Xapian::TermIterator i = document.termlist_begin(); for ( ; i != document.termlist_end(); ++i) { make_term(*i); LOGLINE(DB, "InMemoryDatabase::finish_add_doc(): adding term " << *i); Xapian::PositionIterator j = i.positionlist_begin(); if (j == i.positionlist_end()) { /* Make sure the posting exists, even without a position. */ make_posting(&doc, *i, did, , i.get_wdf(), false); } else { positions_present = true; for ( ; j != i.positionlist_end(); ++j) { make_posting(&doc, *i, did, *j, i.get_wdf()); } } Assert(did > && did <= doclengths.size()); doclengths[did - 1] += i.get_wdf(); totlen += i.get_wdf(); postlists[*i].collection_freq += i.get_wdf(); ++postlists[*i].term_freq; } swap(termlists[did - 1], doc); totdocs++; }
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/26692020/viewspace-3119421/ ,如需转载,请注明出处,否则将追究法律责任。