我希望SOLR的搜索结果如下:
所有具有相同分数的文档将按添加日期降序排序.
所以当我查询solr时,我会有n个文件.在此结果集中,将存在具有相同分数的文档组.我希望这组文档中的每一个都按照添加日期的顺序递减.
我发现我可以使用函数查询完成此操作,更准确地说是使用rord函数http://wiki.apache.org/solr/FunctionQuery#rord,但正如文档中所述
警告:从Solr 1.4开始,ord()和rord()会导致超额内存使用,因为它们必须在顶级读取器中使用FieldCache条目,而排序和函数查询现在使用段级别的条目.因此,除了ord()/ rord()之外,排序或使用不同的函数查询将使内存使用倍增.
它会导致过多的内存使用.
我还有其他选择吗?
我在考虑使用recip(ms(NOW,startTime),1,1,0).这是最好的方法吗?
如果我使用recip和ms,是否会对性能产生负面影响?
MySQL提供FULLTEXT可以使用MATCH (col1,col2,...) AGAINST (expr [search_modifier])构造检索的索引.有几种全文搜索变体,其中一种(和默认的)是自然语言全文搜索.
那么MATCH的最大可能值是什么('...'IN NATURAL LANGUAGE MODE)?
例:
这个查询
SELECT
courses.id,
courses.title,
MATCH (coursedata.title) AGAINST ('Basketball') AS relevance
FROM
courses
JOIN
coursedata ON coursedata.id = courses.coursedata_id
WHERE
MATCH (coursedata.title) AGAINST ('Basketball') > 0
Run Code Online (Sandbox Code Playgroud)
返回带有列的结果表relevance,我们在其中存储coursedata.title行的相关性值'Basketball'.或相关值'Basketball'的coursedata.title行?无论如何,我们在那里存储MATCH(...)函数的输出.就我而言,我从歌厅值0来3.695953130722046.
我已经创建了一个非常高级的搜索我正在研究的Wordpress网站.允许访问者按不同的分类法过滤结果,按日期或自定义字段以及正常的自由文本搜索(WP默认提供)对其进行排序.
我已经使用pre_get_posts过滤器完成了这个,只需将我的东西添加到查询中,就像这样:(请注意,我遗漏了一些健全性检查和其他代码)
<?php
add_filter('pre_get_posts', 'my_search');
function my_search ($qry) {
# Include more post types
$qry->set('post_type', array('foo', 'bar'));
if ($_GET['myorder'] == 'price') {
$qry->set('orderby', 'meta_value_num');
$qry->set('meta_key', 'price');
$qry->set('order', 'ASC');
}
else {
$qry->set('orderby', 'date');
$qry->set('order', 'DESC');
}
}
Run Code Online (Sandbox Code Playgroud)
现在我想添加另一种方式来对帖子进行排序,即通过相关性.我知道这是一个非常常见的请求,我遇到的问题的大多数解决方案都包括使用Relevanssi插件.看来我已经编写了自己的"插件"(好吧,代码至少)并且我的所有搜索表单和列表都设置为使用它,切换到Relevanssi在这一点上不会太容易.
Sooo,我想知道是否有人知道一些(最好)简单的方法来添加我已经获得的代码?
据我了解,WP使用LIKE而不是使用它进行搜索MATCH(),这就是为什么它甚至没有相关性得分可以排序.如果这是正确的,我假设我必须完全编写自己的查询?如何在不搞乱WP的分页等的情况下做到这一点?或者我可以添加类似$qry->set('WHERE', "MATCH(post_content) AGAINST('$q' IN BOOLEAN MODE) AS relevance"); $qry->set('sortby', 'relevance')你认为的东西吗?
我正在编写一个预测搜索,为了服务器性能要求(所有都是缓存的),必须在客户端浏览器上运行.这些项目是电视节目和电影,并由标题,演员和导演名称匹配.执行搜索后,它会返回一个匹配项列表,每个结果有两个值:
匹配单词的数量(n):用户可以输入4个单词,但只有2个单词与一个项目匹配.越多越好.
在莱文斯坦编辑距离增加(LD).用户可以输入3个单词,但其中有2个单词与索引的单词有拼写错误或其他小差异.我使用编辑距离来查找最近的索引字.所有Levenshtein距离的添加都作为接近指示符返回.越少越好.
要求
客户端.没有Sphinx,Lucene或任何其他服务器端解决方案.
速度超过准确性.该算法在每次击键时运行,我们不想让用户厌烦.保持大O不是那么大.
非递归.每个项目相关性的计算不应该依赖于其他项目计算.我不想击败谷歌,只提供小套装的最佳效果.
有界形式0到1,0到100或类似的东西.不是必需品,但能够显示"相关百分比"是一个加分.
关于实施的想法.我正在寻找一种比特定实现更好的算法/公式.
我的aproach
基于指数衰减(如放射性半衰期分解),我编制了这个公式.

哪里:
T 是用户提供的单词数.n 是匹配单词的数量.ld 是这个匹配单词的Levenshtein距离加法.在伪代码中.
function lambda(n, ld) {
lambda = (n/T) * e^(-ld * 1/n);
return lambda;
}
Run Code Online (Sandbox Code Playgroud)
一点解释:
-ld * 1/n是相关性度量核心.如果ld是低并且n很大,它接近于零(-0侧)并且表明该结果更相关.
n/T是准确率.匹配单词与所有单词.通过考虑总用户输入来优化先前的相关性.
对于负数幂,指数函数将结果限制在0和1之间.
最后,问题
我想要的不是基于具有额外编辑距离计算的响应来细化搜索算法,而是通过将相关值设置为每个来改进返回元素的相关性排序.如果可以使用除了n并且ld需要且易于计算的任何参数.在我的解决方案中,我添加T了用户提供的单词数.
我想把像'吃'这样的字符串转换成'吃','吃'.我搜索并发现了词形还原作为解决方案,但我遇到的所有lemmatizer工具都使用wordlist或字典查找.是否存在避免字典查找并提供高效率的词形变换器,可能是基于规则的词形变换器.是的,我不是在寻找"干扰者".
我正在尝试通过相关性对我的全文搜索进行排序.这是我的代码,如果删除ORDER BY但不按相关性排序.我试过这个,它实际上是因为它没有找到任何结果......任何想法?
$query_for_result=mysql_query("
SELECT * FROM Assets WHERE MATCH
(`Badge`,`First Name`,`Last Name`,`Service Tag`,`Asset Tag`)
AGAINST ('".$query."*' IN BOOLEAN MODE) and
`deleted` = '0' ORDER BY relevance DESC");
Run Code Online (Sandbox Code Playgroud)
编辑*
<input type="text" name="query" />
<input type="hidden" value="Search" name="submit" />
<input type="submit" name="submit" value="Search" />
</form>
<h4>Search by: Badge, First or Last Name, Service Tag, Asset Tag, Printer Queue or Printer IP.</h4>
<br>
</center>
<?php
if(isset($_GET['submit'])){
$db_tb_name=Assets;
$db_tb_atr_name=`First Name`;
$query=mysql_real_escape_string($_GET['query']);
$query_for_result=mysql_query("
SELECT * FROM Assets WHERE MATCH
(`Badge`,`First Name`,`Last Name`,`Service Tag`,`Asset Tag`)
AGAINST …Run Code Online (Sandbox Code Playgroud) 我希望我的搜索结果按照他们正在进行的分数排序,但分数计算不正确.这就是说,不一定是不正确的,但与预期不同,我不知道为什么.我的目标是删除任何改变分数的内容.
如果我执行匹配两个对象的搜索(其中ObjectA的分数高于ObjectB),则首先返回ObjectB.
让我们说,对于这个例子,我的查询是一个单词:"apples".
ObjectA的标题:"苹果是苹果"(2/3条款)
ObjectA的描述:"苹果 - 苹果中有苹果,现在苹果遍布苹果的所有苹果!" (6/18条款)
ObjectB的标题:"苹果很棒"(1/3条款)
ObjectB的描述:"苹果室里有苹果,现在苹果在苹果上都变坏了!" (4/18条款)
标题字段没有提升(或者更确切地说,提升为1),描述字段的提升为0.8.我没有通过solrconfig.xml或通过我正在通过的查询指定文档提升.如果有另一种指定文档提升的方法,那么我有可能错过一个.
在分析explain打印输出之后,看起来ObjectA 正在计算比ObjectB更高的分数,就像我想要的那样,除了一个区别:ObjectB的标题fieldNorm总是高于ObjectA.
以下是explain打印输出.您知道:标题字段是mditem5_tns,描述字段是mditem7_tns:
ObjectB:
1.3327172 = (MATCH) sum of:
1.0352166 = (MATCH) max plus 0.1 times others of:
0.9766194 = (MATCH) weight(mditem5_tns:appl in 0), product of:
0.53929156 = queryWeight(mditem5_tns:appl), product of:
1.8109303 = idf(docFreq=3, maxDocs=9)
0.2977981 = queryNorm
1.8109303 = (MATCH) fieldWeight(mditem5_tns:appl in 0), product of:
1.0 = tf(termFreq(mditem5_tns:appl)=1)
1.8109303 = idf(docFreq=3, maxDocs=9)
1.0 = …Run Code Online (Sandbox Code Playgroud) 我最近安装了solr.示例索引(在apache-solr中找到 - #.#.#\ example\solr)似乎可以工作,并且一旦复制到我的solr主目录,我就可以通过管理页面访问它.但是,当我尝试通过替换schema.xml内容(从此处获取)来实现新索引时:
<?xml version="1.0" encoding="UTF-8" ?>
<schema name="example" version="1.2">
<types>
<fieldType name="string" class="solr.StrField" sortMissingLast="true" omitNorms="true" />
<fieldType name="int" class="solr.TrieIntField" precisionStep="0" omitNorms="true" positionIncrementGap="0" />
<fieldType name="date" class="solr.TrieDateField" omitNorms="true" precisionStep="0" positionIncrementGap="0" />
<fieldType name="text" class="solr.TextField" positionIncrementGap="100">
<analyzer type="index">
<tokenizer class="solr.WhitespaceTokenizerFactory" />
<filter class="solr.StopFilterFactory" ignoreCase="true" words="stopwords.txt" enablePositionIncrements="true" />
<filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0" splitOnCaseChange="1" />
<filter class="solr.LowerCaseFilterFactory" />
<filter class="solr.SnowballPorterFilterFactory" language="English" protected="protwords.txt" />
</analyzer>
<analyzer type="query">
<tokenizer class="solr.WhitespaceTokenizerFactory" />
<filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true" />
<filter class="solr.StopFilterFactory" …Run Code Online (Sandbox Code Playgroud) 当我使用"匹配所有文档"查询' *:*',星号冒号星号时,结果如何排序?
我认为它们按相关性排序,但在这种情况下相关性是相同的,对吧?那么,这个计划是什么?
Elasticsearch在排名时将文档的长度考虑在内(他们称这个字段为规范化).默认行为是将较短的匹配文档排名高于较长的匹配文档.
无论如何在查询时关闭或修改字段规范化?我知道索引时间omit_norms选项,但我宁愿不重新索引所有内容来尝试这一点.
而且,我想尝试一些事情,而不是简单地关闭字段规范化.我想考虑字段长度,但不像弹性搜索目前那么重要.使用默认行为,文档的排名将比文档的排名高2倍.我想尝试排名和长度之间的非线性关系.
relevance ×10
solr ×4
mysql ×2
search ×2
algorithm ×1
client-side ×1
java ×1
javascript ×1
lucene ×1
php ×1
solr-boost ×1
sql-order-by ×1
tf-idf ×1
wordpress ×1