-1

Following is my simple code, index function establishes indexers and search function searches using querystring directly:

#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();
}

run the app, I got:

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

Actually I want to get:

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

Did I make some mistakes? or missed something or just used wrong query string?

PS: I am a beginner learning to Xapian.

shoutrain
  • 21
  • 3
  • 1
    Did you try it? What was the result? Give a [MCVE]! – jkalden Jan 16 '16 at 08:49
  • Yes, my workmates tried: age:1..200 - age:80..100, I got results with age from 80 to 100 age:1..79 + age:101..200, no results age:1..79 OR age:101..200, no results Maybe they made mistakes. Actually they are using XunSearch, a set of PHP API based on Xapian. – shoutrain Jan 17 '16 at 01:07
  • You need to share some code if you want help. Please traf [ask] to learn how [so] works and then give a [mcve], i. e. share some code! And please don't blame others! Check your code for mistakes before asking here! – jkalden Jan 17 '16 at 06:40
  • Hope current content meets the requirement. – shoutrain Jan 19 '16 at 14:23
  • Check out the [documentation on searching value ranges using Xapian](http://getting-started-with-xapian.readthedocs.org/en/latest/howtos/range_queries.html). In particular, I think you need to (a) serialise your numbers using Xapian's utility for that purpose, and (b) add a `ValueRangeProcessor` of some sort (probably a `NumberValueRangeProcessor`). – James Aylett Jan 19 '16 at 19:13

1 Answers1

1

Thank you, @jkalden, @James Aylett. I just got the results I want. Yes, Xapian::sortable_serialise() is key to solve my problem.

#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();
}

Following is the output:

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
shoutrain
  • 21
  • 3