Xapian是否支持查询字符串,如" x:1..2或x:8..10"?我想不明白

时间:2016-01-16 08:37:57

标签: range xapian

以下是我的简单代码,索引函数直接使用查询字符串建立索引器和搜索函数搜索:

#include <xapian.h>
#include <stdlib.h>

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

int index() {
    try {
        Xapian::WritableDatabase db("./index.db", Xapian::DB_CREATE_OR_OPEN);
        Xapian::TermGenerator indexer;
        Xapian::Stem stemmer("english");
        indexer.set_stemmer(stemmer);

        for (int i = 1; i < 12; i++) {
            Xapian::Document doc;
            indexer.set_document(doc);

            string title("title ");
            string desc("example data with number of ");
            stringstream num;

            num << i;
            title.append(num.str());
            desc.append(num.str());

            indexer.index_text(title, 1, "S");
            indexer.index_text(desc, 1, "XD");

            indexer.index_text(title);
            indexer.increase_termpos();
            indexer.index_text(desc);

            doc.set_data(num.str() + "\n" + title + "\n" + desc);
            doc.add_value(1, num.str());

            string idterm = "Q" + num.str();
            doc.add_boolean_term(idterm);
            db.add_document(doc);
        }

        db.commit();
    } catch (const Xapian::Error &e) {
        cout << e.get_description() << endl;

        return 1;
    }

    return 0;
}

int search() {
    try {
        Xapian::Database db("./index.db");

        Xapian::Enquire enquire(db);
        // Xapian::Query query("");
        Xapian::Query queryLeft(Xapian::Query::OP_VALUE_RANGE, 1, "1", "2");
        Xapian::Query queryRight(Xapian::Query::OP_VALUE_RANGE, 1, "8", "11");
        Xapian::Query query(Xapian::Query::OP_OR, queryLeft, queryRight);

        cout << "Parsed query is: " << query.get_description() << endl;
        enquire.set_query(query);

        Xapian::MSet matches = enquire.get_mset(0, 11);

        cout << matches.get_matches_estimated() << " results found.\n";
        cout << "Matches 1-" << matches.size() << ":\n" << endl;

        for (Xapian::MSetIterator i = matches.begin(); i != matches.end();
                ++i) {
            cout << i.get_rank() + 1 << ":" << i.get_percent() << "%" << endl;
            cout << i.get_document().get_data() << endl << endl;
        }
    } catch (const Xapian::Error &e) {
        cout << e.get_description() << endl;

        return 1;
    }

    return 0;
}

int main() {
    index();
    search();
}

运行应用程序,我得到了:

Parsed query is: Xapian::Query((VALUE_RANGE 1 1 2 OR VALUE_RANGE 1 8 11))
8 results found.
Matches 1-8:

1:100%
1
title 1
example data with number of 1

2:100%
2
title 2
example data with number of 2

3:100%
10
title 10
example data with number of 10

4:100%
11
title 11
example data with number of 11

5:100%
1
title 1
example data with number of 1

6:100%
2
title 2
example data with number of 2

7:100%
10
title 10
example data with number of 10

8:100%
11
title 11
example data with number of 11

其实我想得到:

1:100%
1
title 1
example data with number of 1

2:100%
2
title 2
example data with number of 2

8:100% #8
8
title 8
example data with number of 8

9:100%
9
title 9
example data with number of 9

10:100%
10
title 10
example data with number of 10

我犯了些错吗?或错过了什么或只是使用错误的查询字符串?

PS:我是学习Xapian的初学者。

1 个答案:

答案 0 :(得分:1)

谢谢@jkalden,@ James Aylett。我得到了我想要的结果。是的,Xapian :: sortable_serialise()是解决我的问题的关键。

#include <xapian.h>
#include <stdlib.h>

#include <iostream>
#include <sstream>
#include <string>

using namespace std;

int index() {
    try {
        Xapian::WritableDatabase db("./index.db", Xapian::DB_CREATE_OR_OPEN);
        Xapian::TermGenerator indexer;
        Xapian::Stem stemmer("english");
        indexer.set_stemmer(stemmer);

        for (int i = 1; i < 12; i++) {
            Xapian::Document doc;
            indexer.set_document(doc);

            string title("title ");
            string desc("example data with number of ");
            stringstream num;

            num << i;
            title.append(num.str());
            desc.append(num.str());

            indexer.index_text(title, 1, "S");
            indexer.index_text(desc, 1, "XD");

            indexer.index_text(title);
            indexer.increase_termpos();
            indexer.index_text(desc);

            doc.set_data(num.str() + "\n" + title + "\n" + desc);
            doc.add_value(0, Xapian::sortable_serialise(i));

            string idterm = "Q" + num.str();
            doc.add_boolean_term(idterm);
            db.add_document(doc);
        }

        db.commit();
    } catch (const Xapian::Error &e) {
        cout << e.get_description() << endl;

        return 1;
    }

    return 0;
}

int search() {
    try {
        Xapian::Database db("./index.db");

        Xapian::Enquire enquire(db);
        Xapian::Query queryLeft(Xapian::Query::OP_VALUE_RANGE, 0,
                Xapian::sortable_serialise(1), Xapian::sortable_serialise(2));
        Xapian::Query queryRight(Xapian::Query::OP_VALUE_RANGE, 0,
                Xapian::sortable_serialise(8), Xapian::sortable_serialise(11));
        Xapian::Query query(Xapian::Query::OP_OR, queryLeft, queryRight);

        cout << "Parsed query is: " << query.get_description() << endl;
        enquire.set_query(query);

        Xapian::MSet matches = enquire.get_mset(0, 10);

        cout << matches.get_matches_estimated() << " results found.\n";
        cout << "Matches 1-" << matches.size() << ":\n" << endl;

        for (Xapian::MSetIterator i = matches.begin(); i != matches.end();
                ++i) {
            cout << i.get_rank() + 1 << ":" << i.get_percent() << "%" << endl;
            cout << i.get_document().get_data() << endl << endl;
        }
    } catch (const Xapian::Error &e) {
        cout << e.get_description() << endl;

        return 1;
    }

    return 0;
}

int main() {
    index();
    search();
}

以下是输出:

Parsed query is: Xapian::Query((VALUE_RANGE 0 � � OR VALUE_RANGE 0 � ��))
6 results found.
Matches 1-6:

1:100%
1
title 1
example data with number of 1

2:100%
2
title 2
example data with number of 2

3:100%
8
title 8
example data with number of 8

4:100%
9
title 9
example data with number of 9

5:100%
10
title 10
example data with number of 10

6:100%
11
title 11
example data with number of 11