2

我正在构建一个具有日历的应用程序,用户可以在其中注释事件。

日历对每个用户都是私有的,也就是说,用户 A 无法看到用户 B 日历上的事件。

我想使用 Zend Lucene 索引日历事件,但我不确定如何执行此操作。

无论用户如何,我都可以让 Lucene 将所有事件索引在一起——但是当搜索完成时,它将向另一个用户显示一个用户的事件,这不是我想要的。

我认为为每个用户创建一个专属索引不是一个好主意,但是我不知道如何:

  • 从所有用户创建日历事件的通用索引
  • 完成搜索后,强制结果仅显示属于执行搜索的用户的事件

关于如何做到这一点的任何想法/建议/指针?

4

2 回答 2

1

Here's how I solved this issue:

First, make sure you include user_id field when building the index

Note that it is wise to use Keyword() for user_id since we want Lucene to search as well as display this data in results.

    $doc = new Zend_Search_Lucene_Document();

    $doc->addField(Zend_Search_Lucene_Field::Keyword('user_id', $row->user_id));
    $doc->addField(Zend_Search_Lucene_Field::UnIndexed('date_1', $row->date_1));
    $doc->addField(Zend_Search_Lucene_Field::Text('title', $row->title));

    $index->addDocument($doc);

     //etc

Next, add a boolean subquery on the backend (programatically) that will force all results to include the query string (user's search input) AND this user's user_id.

    $index = Zend_Search_Lucene::open($this->search_index);

    // add user's input to parser
    $query      = Zend_Search_Lucene_Search_QueryParser::parse($query_string);

    // add boolean query
    $query_bool = new Zend_Search_Lucene_Search_Query_Boolean();

    // add user id as a term
    // note this is saying that a specific `user_id`
    // must be found in a specific field (user_id)
    $user_id    = get_user_id(); // or use your own 'get user id' function 
    $term       = new Zend_Search_Lucene_Index_Term($user_id, 'user_id');
    $subquery1  = new Zend_Search_Lucene_Search_Query_Term($term);

    // construct boolean requiring both user id and string
    $query_bool->addSubquery($query, true);     // required
    $query_bool->addSubquery($subquery1, true); // required

    $query_result = $index->find($query_bool);

And there you have it.

Now if user 123 searches for 'appointment', Lucene will make the search actually be something like appointment AND user_id=123.

Let me know if there's any way to improve this - glad to discuss.

于 2011-12-02T14:33:15.737 回答
0

我没有尝试过,但它可能会起作用。

您可以在 user_id 字段中索引 ID,并在“user_id”字段中搜索必须具有的搜索事件,在您的情况下为数字:

$query = new Zend_Search_Lucene_Search_Query_Phrase(array('333'), null, 'user_id');
$hits1 = $index->find($query);

这将在“user_id”字段中搜索“333”短语。

我不确定这是否会返回给您所有索引 '333' 数字,如 '3334'、'3335'、......你必须尝试。如果这返回给您所有其他结果(3334、3335、...),您可以设置您只想搜索“333”,但我将其留给您的研究 :)

你可以在这里找到所有你需要的东西: Zend_Search


在任何情况下,您都可以将 user_id 存储在索引中。比当有人搜索事件时,您必须仅显示具有以下内容的结果:

来自索引的 user_id == 来自会话的 user_id,这肯定会起作用。

于 2011-12-02T09:01:20.657 回答