查询嵌入式列表与OrientDB中的其他属性相结合

时间:2016-03-27 06:39:14

标签: java sql orientdb

我正在尝试在我的Java应用程序中查询OrientDB中的嵌入式列表,但是当我将该属性与其他属性组合时,我很难查询该属性。

例如,这可行(类别是字符串的嵌入列表):

select from Book where categories = :category

然而,当我这样查询时:

select from Book where categories = :category and year = 1980

然后突然我的查询不再给出任何结果,而1980年我的数据库中肯定有这类书籍。实际上,我的网站或1980年的所有书籍(但后来,我还会增加1981年和1982年的书籍等)。

两个字段都已编入索引(NONUNIQUE索引)。就像测试一样,我删除了年份的索引,不料,查询再次正常运行。现在我很困惑:))

1 个答案:

答案 0 :(得分:5)

我用这个简单的结构尝试了你的案例:

CREATE CLASS Books

CREATE PROPERTY Books.title STRING
CREATE PROPERTY Books.categories EMBEDDEDLIST STRING
CREATE PROPERTY Books.year INTEGER

CREATE INDEX Books.categories ON Books(categories) NOTUNIQUE
CREATE INDEX Books.year ON Books(year) NOTUNIQUE

INSERT INTO Books(title, categories, year) VALUES('BookA', ['Fantasy','Adventure'], 1980)
INSERT INTO Books(title, categories, year) VALUES('BookA', ['Fantasy'], 1985)
INSERT INTO Books(title, categories, year) VALUES('BookA', ['Horror','Adventure'], 1984)
INSERT INTO Books(title, categories, year) VALUES('BookA', ['Adventure'], 1980)
INSERT INTO Books(title, categories, year) VALUES('BookA', ['Historical'], 1981)
INSERT INTO Books(title, categories, year) VALUES('BookA', ['Thriller'], 1990)

这是课程Books中的结果:

SELECT FROM Books

----+-----+------+-----+----------+----
#   |@RID |@CLASS|title|categories|year
----+-----+------+-----+----------+----
0   |#12:0|Books |BookA|[2]       |1980
1   |#12:1|Books |BookA|[1]       |1985
2   |#12:2|Books |BookA|[2]       |1984
3   |#12:3|Books |BookA|[1]       |1980
4   |#12:4|Books |BookA|[1]       |1981
5   |#12:5|Books |BookA|[1]       |1990
----+-----+------+-----+----------+----

问题可能在于使用=而不是IN运算符,因为categoriesEMBEDDEDLISTIN运算符会检查在列表的每个值中都存在输入参数(而=检查参数值是否与列表值完全相同)。

<强> OSQL

1)使用=

SELECT FROM Books WHERE categories = 'Adventure' AND year = 1980

0 item(s) found. Query executed in 0.0 sec(s).

2)使用IN

SELECT FROM Books WHERE 'Adventure' IN categories AND year = 1980

----+-----+------+-----+----------+----
#   |@RID |@CLASS|title|categories|year
----+-----+------+-----+----------+----
0   |#12:0|Books |BookA|[2]       |1980
1   |#12:3|Books |BookA|[1]       |1980
----+-----+------+-----+----------+----

3)使用CONTAINS

SELECT FROM Books WHERE categories CONTAINS 'Adventure' AND year = 1980

----+-----+------+-----+----------+----
#   |@RID |@CLASS|title|categories|year
----+-----+------+-----+----------+----
0   |#12:0|Books |BookA|[2]       |1980
1   |#12:3|Books |BookA|[1]       |1980
----+-----+------+-----+----------+----

<强> JAVA

private static String remote = "remote:localhost/";

public static void main(String[] args) {
    String dbName = "DBname";
    String path = remote + dbName;
    OServerAdmin serverAdmin;
    try {
        serverAdmin = new OServerAdmin(path).connect("root", "root");
        if (serverAdmin.existsDatabase()) {
            System.out.println("Database '" + dbName + "' already exists");
            ODatabaseDocumentTx db = new ODatabaseDocumentTx(path);
            db.open("root", "root");
            Iterable<ODocument> results = db.command(new OSQLSynchQuery<ODocument>(
                    "SELECT FROM Books WHERE 'Adventure' IN categories AND year = 1980")).execute();
            for (ODocument result : results) {
                System.out.println("Title: " + result.field("title") + "   Category: " + result.field("categories")
                        + "   Year: " + result.field("year"));
            }
            db.close();
        } else {
            serverAdmin.createDatabase(dbName, "document", "plocal");
            System.out.println("Database " + dbName + " created");
        }
        serverAdmin.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

<强>输出

Database 'DBname' already exists

Title: BookA   Category: [Fantasy, Adventure]   Year: 1980
Title: BookA   Category: [Adventure]   Year: 1980

希望有所帮助