小编AHu*_*ist的帖子

关于如何改进当前模糊搜索实现的建议

我正在努力实现术语Web服务的模糊搜索,我正在寻找关于如何改进当前实现的建议.分享的代码太多了,但我认为解释可能足以提出深思熟虑的建议.我意识到这是很多东西,但我很感激任何帮助.

首先,术语基本上只是一些名称(或术语).对于每个单词,我们按空格将其拆分为标记,然后遍历每个字符以将其添加到trie.在终端节点上(例如当达到草莓中的字符y时),我们在列表中存储主术语列表的索引.因此,终端节点可以具有多个索引(因为草莓的终端节点将匹配'草莓'和'对草莓过敏').

对于实际搜索,搜索查询也按空间分解为标记.为每个令牌运行搜索算法.搜索令牌的第一个字符必须匹配(因此traw永远不会匹配草莓).之后,我们通过每个连续节点的子节点.如果有匹配的字符的子项,我们继续使用搜索令牌的下一个字符进行搜索.如果孩子与给定的角色不匹配,我们会使用搜索令牌的当前角色来查看孩子(因此不会推进它).这是模糊部分,因此'stwb'将匹配'草莓'.

当我们到达搜索令牌的末尾时,我们将搜索该节点处的其余trie结构以获得所有可能的匹配(因为到主术语列表的索引仅在终端节点上).我们称之为卷起.我们通过在BitSet上设置它们的值来存储索引.然后,我们简单地从每个搜索令牌的结果中得到BitSets.然后,我们从anded BitSet中获取前1000或5000个索引,并找到它们对应的实际项.我们使用Levenshtein对每个术语进行评分,然后按分数进行排序以获得最终结果.

这种方法效果很好而且非常快.树中有超过390k个节点,超过110万个实际术语名称.但是,现在存在问题.

例如,当我们不想要它时,搜索'car cat'将返回Catheterization(因为搜索查询是两个单词,结果应该至少为两个).这很容易检查,但它不会像导管过程那样处理,因为它是两个字.理想情况下,我们希望它与Cardiac Catheterization相匹配.

基于纠正这个问题的需要,我们想出了一些改变.首先,我们通过混合深度/广度搜索来检查trie.基本上,只要角色匹配,我们就会先进入深度.那些不匹配的子节点将添加到优先级队列中.优先级队列按编辑距离排序,可以在搜索特里时计算(因为如果有字符匹配,则距离保持不变,如果不匹配,则增加1).通过这样做,我们得到每个单词的编辑距离.我们不再使用BitSet了.相反,它是Terminfo对象的索引映射.此对象存储查询短语的索引以及术语短语和分数.因此,如果搜索是"汽车猫"并且匹配的术语是"导管过程" 术语短语索引将是1,查询短语索引也是如此.对于"心脏导管",术语短语索引将是1,2,查询短语索引也是如此.正如您所看到的,之后查看术语短语索引和查询短语索引的计数非常简单,如果它们不至少等于搜索词计数,则可以将它们丢弃.

之后,我们将单词的编辑距离相加,从与术语短语索引匹配的术语中删除单词,并计算剩余的字母以获得真正的编辑距离.例如,如果您将术语"过敏与草莓"匹配并且您的搜索查询为"稻草",您将从草莓中获得7分,那么您将使用术语短语索引从该术语中丢弃草莓,并且只计算"过敏"(减去空格)得分为16分.

这让我们得到了我们期望的准确结果.但是,它太慢了.在一个单词搜索之前我们可以获得25-40毫秒,现在它可能多达半秒.它主要来自实例化TermInfo对象,使用.add()操作,.put()操作以及我们必须返回大量匹配这一事实.我们可以将每次搜索限制为仅返回1000个匹配,但不能保证"car"的前1000个结果将匹配"cat"的前1000个匹配中的任何一个(记住,有超过1.1万个术语).

即使对于像cat一样的单个查询词,我们仍然需要大量的匹配.这是因为如果我们搜索'cat',搜索将匹配汽车并汇总其下方的所有终端节点(这将是很多).但是,如果我们限制结果的数量,则会过于强调以查询开头而不是编辑距离的单词.因此,像导尿管这样的词语比涂层更容易被包括在内.

那么,基本上,对于我们如何处理第二个实现修复的问题有什么想法,但没有引入的速度减慢那么多吗?我可以包含一些选定的代码,如果它可以使事情更清楚,但我不想发布一个巨大的代码墙.

java algorithm performance fuzzy-search levenshtein-distance

9
推荐指数
1
解决办法
1407
查看次数

即使访问本地状态,始终使用访问器方法是最佳做法吗?

考虑以下课程:

public class Person 
{
private Integer age;

// Standard Accessors
public Integer getAge() {
    return age;
}

public void setAge(Integer age) {
    this.age = age;
}

public String getAgeAsTextString()
{
    if (this.age == 20)
    {
        return "Twenty";
    }
    return "Unknown";
}
}
Run Code Online (Sandbox Code Playgroud)

我只有1个整数和2个访问器.如果我想创建一个实用程序方法,将对象的状态作为String返回,那么最好将类变量引用为this.age或应该使用getAge()

是否有最佳实践或是由于开发人员的压制?

java

9
推荐指数
2
解决办法
3278
查看次数

是否可以用Hudson/Jenkins中的参数化字符串替换整个Repository Url?

在Hudson/Jenkins中,是否可以使用String参数替换Subversion模块存储库URL中的整个字符串?我不想只更换版本或类似的东西,我想替换整个网址.

所以,当我运行构建时,我会得到一个URL的提示,我会写一些像"http://scm.work.corp/svn/com.work.package/tags/project-4.0.0 .RELEASE"它会检查并构建它.

能够替换"com.work.package"和"project-4.0.0.RELEASE"部分将是可以接受的.我基本上希望它是一个可以构建任何版本的工作.

svn hudson parameterized jenkins

9
推荐指数
2
解决办法
1万
查看次数

Hibernate批量插入.它会使用一个插入而不是多个插入吗?

我一直在寻找确定一些我不确定的Hibernate行为.在正确设置Hibernate批处理的情况下,它是否只在发送批处理时使用多个插入语句?是否无法使用DB独立的多插入语句?

我想我正在尝试确定我是否确实正确设置了批处理.我看到多个insert语句,但后来我也看到"执行批量大小:25"这一行.

我可以发布很多代码,但我试图保持这种一般性.所以,我的问题是:

1)您可以在日志中读到什么以确定正在使用批处理?

2)是否可以使Hibernate使用多行插入而不是多个插入语句?

java oracle hibernate batch-file

9
推荐指数
1
解决办法
5447
查看次数

池大小如何实际与Spring的计划任务一起使用?

我有一个如此安排的任务:

<task:scheduler id="notification.scheduler" pool-size="15" />

<task:scheduled-tasks scheduler="notification.scheduler">
    <task:scheduled ref="notificationProcessor" method="sendNextQueueEvent" fixed-rate="500" />
    <task:scheduled ref="notificationProcessor" method="deleteNextCompletedEvent" fixed-rate="60000" />
</task:scheduled-tasks>
Run Code Online (Sandbox Code Playgroud)

我想我对计划任务如何处理池大小有误解.尽管池大小为15,但似乎只使用了一个线程.例如,如果队列中有15个事件,我认为每分钟会有15个线程检查从队列中删除事件.显然,这是错误的.

我怎样才能使用Spring的调度程序抽象在15个线程中调用此方法的时间间隔?

编辑:我想要完成的是:每半秒,我想检查是否有排队的事件要发送.完成后,我想发送最多15个(如果存在15个).如何使用java线程的弹簧抽象来实现这一点?

java spring scheduled-tasks threadpool

9
推荐指数
2
解决办法
1万
查看次数

修改Levenshtein距离算法不计算所有距离

我正在进行模糊搜索实现,作为实现的一部分,我们使用的是Apache的StringUtils.getLevenshteinDistance.目前,我们正在寻找模糊搜索的特定最大平均响应时间.经过各种改进和一些剖析后,花费最多时间的地方是计算Levenshtein距离.它占搜索字符串总时间的大约80-90%三个字母或更多.

现在,我知道在这里可以做些什么有一些限制,但我已经读过以前的SO问题和LD的维基百科链接,如果有人愿意将阈值限制在设定的最大距离,这可能有助于遏制花在算法上的时间,但我不确定如何准确地做到这一点.

如果我们仅对距离感兴趣,如果它小于阈值k,那么在矩阵中计算宽度为2k + 1的对角条纹就足够了.这样,算法可以在O(kl)时间内运行,其中l是最短字符串的长度.[3]

下面你将看到StringUtils的原始LH代码.之后是我的修改.我试图基本上计算设定长度与i,j对角线的距离(因此,在我的例子中,i,j对角线上方和下方的两个对角线).但是,这是不正确的,因为我已经这样做了.例如,在最高的对角线上,它总是会直接在上面选择单元格值,这将是0.如果有人能告诉我如何使这个功能如我所描述的那样,或者如何使它成为如此的一般建议, 这将不胜感激.

public static int getLevenshteinDistance(String s, String t) {
        if (s == null || t == null) {
            throw new IllegalArgumentException("Strings must not be null");
        }

        int n = s.length(); // length of s
        int m = t.length(); // length of t

        if (n == 0) {
            return m;
        } else if (m == 0) {
            return n;
        }

        if (n > m) {
            // swap the input strings to consume less memory
            String …
Run Code Online (Sandbox Code Playgroud)

java algorithm performance levenshtein-distance

8
推荐指数
2
解决办法
7358
查看次数

什么是Java 1.4.2等效的Pattern.quote()

什么是Java 1.4.2等效的Pattern.quote?

我在URI上使用Pattern.quote()但现在需要使它与1.4.2兼容.

java regex java1.4

7
推荐指数
1
解决办法
987
查看次数

如何将分支扩展到从Crucible开始的主干版本?

我想知道如何使用Crucible,我可以包含diff文件,它只包含从我从主干分支出来的分支中所做的更改.目前,如果我包含类似更改集的内容,则会将分支中的每个文件计为新文件,因此不会显示任何差异.有没有办法做到这一点?

我知道我可以选择每个文件来执行从分支版本到最后一个主干版本的差异,但这对于我更改的文件数量来说非常耗时,我担心我可能会忘记一个.有没有更好的办法?

svn atlassian-fisheye atlassian-crucible

7
推荐指数
1
解决办法
2326
查看次数

使Jackson在序列化时不输出类名(使用Spring MVC)

有没有办法迫使杰克逊不要把类名放在Json输出中?我问了一个问题,导致这个问题,但我要问什么,我希望是一个更集中的问题.我这样做是在使用Spring MVC,但我不确定这有多重要.

所以,而不是


{"NamedSystem":{"name":"Bob Dole","id":"0198b96c-fe18-4aa6-9e61-b5f7149414c2"}}

我想要


{"name":"Bob Dole","id":"0198b96c-fe18-4aa6-9e61-b5f7149414c2"}

我可能更喜欢前者,但我不知道如何让杰克逊在反序列化时识别出类名,所以如果有人知道,那也会有所帮助.

java serialization annotations spring-mvc jackson

6
推荐指数
1
解决办法
9038
查看次数

joda-time 1.6.2 jar无法从maven中央存储库下载

我是一个问题,我正试图引入joda-time jar,但由于某些原因Eclipse无法找到它.这是我收到的消息:1/25/11 11:53:22 AM CST: Missing artifact joda-time:joda-time:jar:1.6.2:compile

这是我的依赖:

<dependency>
   <groupId>joda-time</groupId>
   <artifactId>joda-time</artifactId>
   <version>1.6.2</version>
  </dependency>
Run Code Online (Sandbox Code Playgroud)

但是,我可以去http://repo1.maven.org/maven2/joda-time/joda-time/1.6.2/,它肯定在那里.

关于为什么看起来我无法找回它的任何想法?如果还有其他任何可能相关的信息,请告诉我,我会将其包括在内.

java maven-2 repository jodatime

6
推荐指数
1
解决办法
5628
查看次数