首页 \ 问答 \ Lucene:使用默认运算符= AND搜索多个字段(Lucene: Searching multiple fields with default operator = AND)

Lucene:使用默认运算符= AND搜索多个字段(Lucene: Searching multiple fields with default operator = AND)

为了允许用户使用Lucene 3.5在多个字段中进行搜索,我目前为每个要搜索的字段创建并添加一个QueryParserDisjunctionMaxQuery 。 这在使用OR作为默认操作符时效果很好,但我现在想要将默认操作符更改为AND以获得更精确(更少)的结果。

问题是, queryParser.setDefaultOperator(QueryParser.AND_OPERATOR)丢失许多文档,因为所有的术语必须至少包含1个字段。

例如,考虑文档的以下数据:title field =“Programming Languages”,body field =“Java,C ++,PHP”。 如果用户搜索Java编程,则该特定文档将不包含在结果中,因为标题或主体字段包含查询中的所有术语,尽管它们组合在一起。 我想这个文件返回上述查询,但不是查询HTML编程

我已经考虑过一个广泛的领域,但我有一些问题。 首先,用户经常在他们的查询中包含每个领域的术语(作者:账单),这对于一个查询字段来说是不可能的。 另外,我用FastVectorHighlighter突出显示某些字段,这些字段需要对它们进行索引和存储。 因此,通过添加一个catchall字段,我将不得不索引大部分相同的数据两次,这是时间和空间消耗。

有任何想法吗?


To allow users to search across multiple fields with Lucene 3.5 I currently create and add a QueryParser for each field to be searched to a DisjunctionMaxQuery. This works great when using OR as the default operator but I now want to change the default operator to AND to get more accurate (and fewer) results.

Problem is, queryParser.setDefaultOperator(QueryParser.AND_OPERATOR) misses many documents since all terms must be in atleast 1 field.

For example, consider the following data for a document: title field = "Programming Languages", body field = "Java, C++, PHP". If a user were to search for Java Programming this particular document would not be included in the results since the title nor the body field contains all terms in the query although combined they do. I would want this document returned for the above query but not for the query HTML Programming.

I've considered a catchall field but I have a few problems with it. First, users frequently include per field terms in their queries (author:bill) which is not possible with a catchall field. Also, I highlight certain fields with FastVectorHighlighter which requires them to be indexed and stored. So by adding a catchall field I would have to index most of the same data twice which is time and space consuming.

Any ideas?


原文:https://stackoverflow.com/questions/13906934
更新时间:2023-07-10 17:07

最满意答案

借助于dyp的帮助,我可以使用以下技术解决此问题:

该解决方案不再使用函数指针,而是依赖于防止隐式转换的代理类:

template <class Source>
struct NoConvert
{
  template <class Dest, class = typename std::enable_if<std::is_same<Source, Dest>::value>::type>
  operator Dest () const = delete;

  template <class Dest, class = typename std::enable_if<std::is_same<Source, Dest>::value>::type>
  operator Dest const & () const;
};

template <class> void func();

template <class A, class T, class U>
static auto test(int) -> decltype( func<A>( std::declval<T&>(), NoConvert<U>() ), std::true_type() );

template <class, class, class>
static std::false_type test(...);

template <class A, class T, class U>
static bool valid()
{
  return std::is_same<decltype(test<A, T, U>(0)), std::true_type>::value;
}

可以像这样使用它:

template <class T>
void func( B &, int const & );

template <class T>
void func( B &, std::string );

template <class T>
void func( A &, std::string const & );

std::cout << valid<A, B, int>() << std::endl;         // true
std::cout << valid<A, B, std::string>() << std::endl; // false
std::cout << valid<A, A, std::string>() << std::endl; // true

通过使用NoConvert的转换运算符,您可以使用值,引用或常量引用来传递它。

例如,在当前使用中,当NoConvert<std::string>的转换运算符由NoConvert<std::string>的值参数触发时,两个重载都是有效的,因此存在不明确性,这意味着SFINAE将剔除并允许std::false_type测试通过。 在常量引用参数的情况下,常量引用超载具有优先权,并且正确地允许std::true_type测试超载传递。

该解决方案还依赖于使用ADL解析函数名称的功能,这对于函数指针方法来说是不可能的。


I was able to solve this using the following technique, thanks to help from dyp:

This solution no longer makes use of function pointers and instead relies on a proxy class that prevents implicit conversion:

template <class Source>
struct NoConvert
{
  template <class Dest, class = typename std::enable_if<std::is_same<Source, Dest>::value>::type>
  operator Dest () const = delete;

  template <class Dest, class = typename std::enable_if<std::is_same<Source, Dest>::value>::type>
  operator Dest const & () const;
};

template <class> void func();

template <class A, class T, class U>
static auto test(int) -> decltype( func<A>( std::declval<T&>(), NoConvert<U>() ), std::true_type() );

template <class, class, class>
static std::false_type test(...);

template <class A, class T, class U>
static bool valid()
{
  return std::is_same<decltype(test<A, T, U>(0)), std::true_type>::value;
}

which can be used like:

template <class T>
void func( B &, int const & );

template <class T>
void func( B &, std::string );

template <class T>
void func( A &, std::string const & );

std::cout << valid<A, B, int>() << std::endl;         // true
std::cout << valid<A, B, std::string>() << std::endl; // false
std::cout << valid<A, A, std::string>() << std::endl; // true

By playing with the conversion operators inside of NoConvert, you can make this work with passing by value, reference, or constant reference.

For example, in the current use, when the conversion operator for NoConvert<std::string> is triggered by a value parameter of std::string, both overloads are valid and thus there is ambiguity, meaning that SFINAE will cull this and allow the std::false_type test to pass. In the case of a constant reference parameter, the constant reference overload has precedence and properly allows the std::true_type test overload to pass.

This solution also relies on the ability to use ADL to resolve the name of the function, which was impossible with the function pointer approach.

相关问答

更多
  • 我在a1.get()= 7时遇到错误; 其中没有运算符“=”匹配这些操作数 没有办法将7转换为A_Impl for operator= ,因为构造函数A_Impl(T) (在此实例中扩展为A_Impl(int)被声明为explicit 。 您可以删除explicit关键字,也可以使用以下方法explicit式创建A_Impl : a1.get() = A_Impl(7); 或者,您也可以声明一个特定的operator= : const A_Impl& operator=(const T&) 对于A_I ...
  • 借助于dyp的帮助,我可以使用以下技术解决此问题: 该解决方案不再使用函数指针,而是依赖于防止隐式转换的代理类: template struct NoConvert { template ::value>::type> operator Dest () const = delete; template
  • 正如评论所暗指的那样,你的问题的答案在于区分“bool”(真正的布尔类型)和BOOL(int的MS类型定义)。 然而,在更广泛的主题上,我已经在代码中完成了完全相同的事情。 如果您在MS平台上,请考虑使用_variant_t或CComVariant:两者基本上都是您想要的。 我最终做了一个自己的转换类,其模板通过默认的方式传递给底层的父类(本例中为_variant_t),并为没有内联转换为MS类类型的构造类型添加特化。 您将不得不为每种类型添加专业化,但在底层类型中没有转化,但通常不会太差。 我应该补充一点 ...
  • 通常,...选项将所需参数传递给基础函数。 但在某些情况下,这确实与列车功能中的现有参数发生冲突。 在polr情况下,这是通过tuneGrid解决的。 查看可用的型号页面并搜索polr。 在公式表示法中,它应如下所示: train(y ~ x1 + x2, data = my_data, method = "polr", trControl = my_control, tuneGrid = expand.grid(method = "probit")) ...
  • parentNode.Left仅键入为BTreeNode 。 无法保证它与TNode相同。 想象一下你有: class SpecialBTreeNode : BTreeNode class BoringBTreeNode : BTreeNode 现在考虑TraverseBreadthFirst(rootNode, ...) 。 什么阻止BoringBTreeNode返回BoringBTreeNode ? // This is entirely valid... Spec ...
  • 你的列表是相当正确的,但strdup和getcwd是POSIX(在C99中没有标准化), get_current_dir_name是GNU(甚至不是POSIX)。 你会发现其他函数返回一些堆分配的数据。 但是在使用它之前,你总是应该阅读一些函数的文档 。 它会告诉你,如果返回的值是堆分配(以及谁和应该如何释放)。 某些函数需要指针的地址,并可能会改变它。 例如getline(3) (POSIX)或asprintf(3)或open_memstream(3) (甚至可能稍后会发生一些分配)。 顺便说一下,像fo ...
  • 保存一小段状态而不存储在cookie中的最好方法是将某些内容保存到您的window.name中。 但它只能使用字符串,所以如果您不仅需要一个数据位,还需要将其另存为JSON字符串。 读书: var keptState; if (window.name !== "") { keptState = JSON.parse(window.name); } 来写: state = { "popupOpened" : true, "popupName" : "otherWindowName" ...
  • 你所特化的类型 - const char&不匹配当你传递一个char时T推导 - 它会推导出char ! (模板类型参数只有在通用引用存在的情况下才可以推断为引用) 所以, template <> bool validate ... 无论如何,你为什么不超载呢? The type you specialized for - const char& does not match what T deduces as when you pass a char - it deduces to cha ...
  • 您在分配之前声明类型。 type C = { a: string, b: number } function f({ a, b }: C = {a:"", b:0}): void { // ... } You declare the type before the assignment. type C = { a: string, b: number } function f({ a, b }: C = {a:"", b:0}): void { // ... }
  • 两者有什么区别? 没有区别 。 在第二种情况下,您要让编译器从特化的签名中执行类型推导 。 因此,两种形式都为T = int声明了Swap()的特化。 什么时候使用另一个?何时使用另一个? 在您的可读性或易维护性方面,当一种形式或另一种形式满足您的要求时,您可以自行决定。 函数名后面的<>是什么? 当它出现在函数名之后 ,它是指定模板参数的语法: template void foo(); foo() ...

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)