java - Neo4j中的Lucene在可靠的搜索查询方面存在一些错误-与OrientDB相比

标签 java lucene neo4j orientdb analyzer

我仍在评估Neo4j与OrientDB。最重要的是,我需要Lucene作为全文索引引擎。因此,我在两个数据库上创建了具有相同数据(300Mio行)的相同架构。我在两个系统中查询不同的事物时也很有经验。我在两侧都使用了标准分析仪。 OrientDB测试查询结果在可靠性和速度方面都很好,而且确实很好。 Neo4j的速度也还可以,但是在大多数情况下,结果还是很糟糕的。因此,让我们来看一下Neo4j Lucene索引的其他问题。我总是给您一个例子,说明它在OrientDB中的外观以及应该从查询中删除的结果集。

因此,在这些示例中,存在具有标题的Appln。在两个数据库中,标题都使用Lucene进行了索引。 Applns也有一个ID,仅用于演示顺序。在每个查询的末尾,我有一些关于它们的问题。获得一些反馈,甚至是答案将是很棒的。

查询0:一字查询,无顺序

这个查询很简单。如果只有一个简单的单词,没有别的什么,应该测试数据库的行为。如您所见,Neo4j的结果要比OrientDB的结果长得多。 OrientDB正在使用TFIDF来使结果简短,并且对实际搜索更加可靠。如您所见,在OrientDB中的第一个结果是SOLAR。 Neo4j也完全缺少这一点。

在Neo4j中:START n = node:titles('title:solar')RETURN n.title,n.ID LIMIT 10


分散有...的太阳辐射屏蔽颗粒和太阳辐射屏蔽树脂材料38321319
用于冷却太阳能电池板底部的太阳能电池的太阳能模块具有进气口和出气口... 12944121
用于太阳能热组件的太阳能建筑构件,太阳能热组件,用于操作太阳能的方法... 324146113
...


在OrientDB中:SELECT标题,Appln WHERE标题中的ID,LUCENE“ solar” LIMIT 10


太阳能24900187
太阳能单元和太阳能设备1876343
带有太阳能集中器的太阳能模块13496706
...


问题:


Neo4j为什么不使用TFIDF或使用它们呢?
Neo4j是否可以使用某些关键字匹配顺序?
是否可以将TFIDF更改为OrientDB中的其他名称?


查询#1:一个单词查询,按ID排序

Neo4j在使用TFIDF之前正在订购ID。从Query#0知道,Neo4j没有使用TFIDF,因此它基本上只是通过Lucene查询的第一个结果进行搜索。在OrientDB中,它仍然按好的TFIDF进行搜索,然后进行排序。

在Neo4j中:START n = node:titles('title:solar')RETURN n.title,n.ID ORDER BY n.ID ASC LIMIT 10


太阳能板318的可堆叠平屋顶/地板框架
用于制造太阳能电池的触点的方法636
太阳能电池及其制造方法1217
...


在OrientDB中:SELECT标题,来自Appln的ID,标题LUCENE“ solar”,按ID ASC LIMIT 10


太阳能单元和太阳能设备1876343
带有太阳能集中器的太阳能模块13496706
太阳能跟踪器太阳能收集器16543688
...


问题:


OrientDB中的搜索应如何按ID排序,并且仍然与它们中最好的TFIDF相匹配。
Neo4j中是否可以在通过ID排序之前订购Lucene匹配项?


查询#2:使用星号搜索的一个单词

搜寻星级对Neo4j结果没有影响。 OrientDB的结果发生了很好的变化。

在Neo4j中:START n = node:titles('title:solar *')RETURN n.title,n.ID ORDER BY n.ID ASC LIMIT 10


太阳能板318的可堆叠平屋顶/地板框架
用于制造太阳能电池的触点的方法636
太阳能电池及其制造方法1217
...


在OrientDB中:SELECT标题,来自Appln的ID,标题LUCENE“ solar *” ORDER BY ID ASC LIMIT 10


高性能太阳能甲烷发生器8354701
全塑料蜂窝太阳能热水器8355379
板式太阳能集热器板芯及其制造方法8356173
...


问题:


Neo4j是否会忽略星级搜索?


查询#3:搜索由空格分隔的2个单词

奇怪的是,您需要在此处将“ title:solar panel”更改为该查询。否则,您只会出错。到目前为止,OrientDB似乎还不错。

在Neo4j中:START n = node:titles(title =“ solar panel”)RETURN n.title,n.ID ORDER BY n.ID ASC LIMIT 10


在817毫秒内传回0列


在OrientDB中:SELECT标题,来自Appln的ID,标题LUCENE“太阳能面板”,ORDER BY ID,ASC LIMIT 10


太阳能板1584567
太阳能板1616547
太阳能板2078382
太阳能板2078383
太阳能板2178466
...


问题:


为什么Neo4j在这里需要特殊的查询,至少不会引发任何错误?
为什么查询失败并且什么也没给?我知道Neo4j在这里搜索小写字母,所以区分大小写。但是为什么会这样呢?我的意思是我使用默认的分析器,Neo4j Lucene的文档说的是正确的,所以它意味着to_lower_letter。


查询#4:现在以大写字母搜索相同的查询

像#3中一样。在Neo4j中,仅搜索返回单词的大写字母结果。 OrientDB结果再次看起来不错。

在Neo4j中:START n = node:titles(title =“ SOLAR PANEL”)返回n.title,n.ID ORDER BY n.ID ASC LIMIT 10


太阳能板348800
太阳能板420683
太阳能面板1393804
太阳能板1584567
太阳能板1616547
...


在OrientDB中:SELECT标题,来自Appln的ID,标题LUCENE“ SOLAR PANEL”,按ID ASC LIMIT 10排序


太阳能板1584567
太阳能板1616547
太阳能板2078382
太阳能板2078383
太阳能板2178466
...


问题:


像#3中一样的问题,如何使用to_lower_letter搜索?


查询#5:合并两个单词并使用星号搜索

在这里,我想将单词搜索与星级搜索结合起来。但是通过相等搜索,我无法找到匹配项,因为他希望该标题像往常一样出现在标题中。但是我不能说“ title:SOLAR PANEL *”。这也是被禁止的。在OrientDB中,一切都很好。

在Neo4j中:START n = node:titles(title =“ SOLAR PANEL *”)返回n.title,n.ID ORDER BY n.ID ASC LIMIT 10


895毫秒内返回0行


在OrientDB中:SELECT标题,来自Appln的ID,标题LUCENE“ SOLAR PANEL *”,按ID ASC LIMIT 10排序


太阳能面板1405717
太阳能板1584567
太阳能板1616547
太阳能板2705081
太阳能电池板2766555
...


问题:


您如何将某些单词与Neo4j中的星级搜索结合起来?


查询6:计算查询结果

我真正需要的最后一件事是快速查找总体上有多少个结果。在这里Neo4j可以更快地找到结果,但总是比OrientDB少找到匹配项。搜索太阳能彼此之间有点亲近。但是另一个测试还没有那么接近。

在Neo4j中:START n = node:titles(“ title:Solar”)RETURN count(*)

143211在220秒内

在OrientDB中:SELECT count(*)标题FROM Appln WHERE标题LUCENE“ Solar” LIMIT -1

148029在50秒内

问题:


如何在两个系统上都缩短查找时间?
为什么两个系统都找到不同数量的匹配项?其他关键字也会发生这种情况。也许使用了其他索引索引?


好了,这就是现在的一切。如果您需要任何其他查询,请告诉我,我会提供。
我认为比较Lucene的实现非常重要,因为Lucene具有数百万个节点,具有许多优势。感谢您的小费。

顺便说一句:请不要提供有关使用Java代码代替查询的提示。我想使用Cypher,因为请求应在浏览器中完成,就像在OrientDB中一样。我知道这里的所有内容都可以轻松地用Java代码完成。谢谢。

最佳答案

好吧,我想分享直到现在为止我对我的问题的发现:

有关查询#0,#1和#2的信息:


无法更改Neo4j的TFIDF。他们正在使用自己的实现,无法更改。
在OrientDB中,搜索之前的排序当前很慢。

SELECT FROM (
  SELECT title,ID FROM Appln WHERE title LUCENE "solar*" ORDER BY ID ASC
)  LIMIT 1

Query executed in 11.531 sec. Returned 1 record(s)


SELECT FROM (
  SELECT title,ID FROM Appln WHERE title LUCENE "solar*" ORDER BY ID ASC
)  LIMIT 10

Query executed in 225.176 sec. Returned 10 record(s)


之所以这么慢是因为它与Lucene不对应。


修正查询#3,#4和#5:

查询不正确。等于是直接匹配,而不是模糊匹配。所以

START n=node:titles(title="solar panel") RETURN n.title,n.ID ORDER BY n.ID ASC LIMIT 10


需要替换为

START n=node:titles('title:solar\\ panel') RETURN n.title,n.ID ORDER BY n.ID ASC LIMIT 10


您需要逃脱密码中的东西的真正糟糕的方法。这两个词的顺序很重要。但是还有另一种说法

START n=node:titles('title:SoLar AND title:Panel') RETURN n.title,n.ID ORDER BY n.ID ASC LIMIT 10


但是如果您有一个字符串并且仅询问Neo4j结果,那真的很糟糕,您需要一个解析器。但是这里的单词顺序并不重要。

解决查询6:

OrientDB当前正在努力使计数更快(毫秒)。计划在几天内发布2.0版。

Neo4j对此没有计划。

关于java - Neo4j中的Lucene在可靠的搜索查询方面存在一些错误-与OrientDB相比,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26497068/

相关文章:

java - JCalendar焦点事件

java - 深层复制中 java.util.Date 的行为

elasticsearch - 在 Elasticsearch 中按精确顺序搜索多个值

lucene - Neo4j - 使用 Lucene 查询

php - 使用 Lucene/PHP 索引大型数据库

java - 如何为嵌入式 Neo4j 数据库执行 Gremlin 脚本?

java - 当负载因子大于 1 时,如何填充 java 中的 hashMap?

java - @Nonnull 注释只是标记?

neo4j - 如何在 Neo4j 中进行简单的推荐

java - 是否有必要从neo4j社区版迁移到企业版以及关于在neo4j中创建新数据库的查询