简体   繁体   English

Algolia:如何只在文本字段中检索第一次出现的搜索查询?

[英]Algolia: how to only retrieve first occurrence of the search query in the text field?

I'm using Algolia for adding search to my JAMStack website.我正在使用 Algolia 将搜索添加到我的 JAMStack 网站。 however, my site has some sort of premium content and I want them to be searchable while remaining hidden to the users.但是,我的网站有一些高级内容,我希望它们是可搜索的,同时对用户保持隐藏。
I can achieve similar functionality by adding the body attribute to the searchable fields and remove it from the retrieved attributes.我可以通过将body属性添加到可搜索字段并将其从检索到的属性中删除来实现类似的功能。 this way Algolia will still search the body for occurrences of the query while not exposing them to the user.这样,Algolia 仍然会在正文中搜索查询的出现,而不会将它们暴露给用户。
But the more preferable behavior is for the user to be able to see one or two occurrences of what he searched for in the retrieved body, but not able to see the whole text of the premium content.但更优选的行为是用户能够在检索到的正文中看到他搜索的内容的一两次出现,但不能看到优质内容的整个文本。

For example, let's say we have the following entities in our index:例如,假设我们的索引中有以下实体:

[
  {
    title: "Hello",
    body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
  },
  {
    title: "Hi",
    body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit"
  }
]

Now, if I query the algolia API with text "i", algolia response looks like this:现在,如果我使用文本“i”查询 algolia API,algolia 响应如下所示:

...
hits: [
  {
    title: "Hello",
    body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
    _highlightResults: {
      body: "Lorem <em>i</em>psum dolor s<em>i</em>t amet, consectetur ad<em>i</em>p<em>i</em>sc<em>i</em>ng el<em>i</em>t, sed do e<em>i</em>usmod tempor <em>i</em>nc<em>i</em>d<em>i</em>dunt ut labore et dolore magna al<em>i</em>qua. Ut en<em>i</em>m ad m<em>i</em>n<em>i</em>m ven<em>i</em>am, qu<em>i</em>s nostrud exerc<em>i</em>tat<em>i</em>on ullamco labor<em>i</em>s n<em>i</em>s<em>i</em> ut al<em>i</em>qu<em>i</em>p ex ea commodo consequat. Du<em>i</em>s aute <em>i</em>rure dolor <em>i</em>n reprehender<em>i</em>t <em>i</em>n voluptate vel<em>i</em>t esse c<em>i</em>llum dolore eu fug<em>i</em>at nulla par<em>i</em>atur. Excepteur s<em>i</em>nt occaecat cup<em>i</em>datat non pro<em>i</em>dent, sunt <em>i</em>n culpa qu<em>i</em> off<em>i</em>c<em>i</em>a deserunt moll<em>i</em>t an<em>i</em>m <em>i</em>d est laborum."
    }
  },
  {
    title: "Hi",
    body: "Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit",
    _highlightResults: {
      body: "Sed ut persp<em>i</em>c<em>i</em>at<em>i</em>s unde omn<em>i</em>s <em>i</em>ste natus error s<em>i</em>t voluptatem accusant<em>i</em>um doloremque laudant<em>i</em>um, totam rem aper<em>i</em>am, eaque <em>i</em>psa quae ab <em>i</em>llo <em>i</em>nventore ver<em>i</em>tat<em>i</em>s et quas<em>i</em> arch<em>i</em>tecto beatae v<em>i</em>tae d<em>i</em>cta sunt expl<em>i</em>cabo. Nemo en<em>i</em>m <em>i</em>psam voluptatem qu<em>i</em>a voluptas s<em>i</em>t aspernatur aut od<em>i</em>t aut fug<em>i</em>t, sed qu<em>i</em>a consequuntur magn<em>i</em> dolores eos qu<em>i</em> rat<em>i</em>one voluptatem sequ<em>i</em> nesc<em>i</em>unt. Neque porro qu<em>i</em>squam est, qu<em>i</em> dolorem <em>i</em>psum qu<em>i</em>a dolor s<em>i</em>t amet, consectetur, ad<em>i</em>p<em>i</em>sc<em>i</em> vel<em>i</em>t"
  }
]

But what I want it to return, is the following:但我希望它返回的是以下内容:

[
  {
    title: "Hello",
    _highlightResults: {
      body: "Lorem <em>i</em>psum dolor sit amet" // only the first occurance with some context
    }
  },
  {
    title: "Hi",
    _highlightResults: {
      body: "Sed ut persp<em>i</em>ciatis unde" // only the first occurance with some context
    }

  }
]

I know something similar to this can be done using the snippets, but if you pay close attention, the body field is also removed from the hit body itself so the complete body is never sent to the client.我知道可以使用代码片段完成类似的操作,但是如果您密切注意,body 字段也会从命中主体本身中删除,因此永远不会将完整的主体发送给客户端。 The client can search through the premium contents while the content itself remains unexposed.客户可以在内容本身保持未公开的情况下搜索优质内容。

How can I achieve this using the Algolia API?如何使用 Algolia API 实现这一目标?

You should be able to implement such logic with snippet .您应该能够使用snippet来实现这样的逻辑。 You don't have to return the field to search for it.您不必返回该字段来搜索它。 The snippet feature can control how much context is sent back with the match.片段功能可以控制与匹配发回的上下文量。 You can set the limit to return only a few words to restrict the match to a single occurrence.您可以将限制设置为仅返回几个单词以将匹配限制为一次出现。 It won't be 100% accurate though, two matches may be returned if they are closer than the given limit (which shouldn't be a problem for a real use case).但它不会 100% 准确,如果两个匹配项更接近给定限制,则可能会返回两个匹配项(这对于实际用例来说应该不是问题)。

The below example only returns the name attribute for the search.下面的示例仅返回搜索的name属性。 The description is set in the searchableAttributes . descriptionsearchableAttributes中设置。 It means that the query will use this attribute for the search.这意味着查询将使用此属性进行搜索。 It also mean that we can use it with the snippet feature.这也意味着我们可以将它与片段功能一起使用。 Here the snippet is restricted to 10 words.这里的片段限制为 10 个单词。

index.search('apple', {
  attributesToRetrieve: ['name'],
  attributesToSnippet: ['description:10'],
});

Note that those values are set at search time.请注意,这些值是在搜索时设置的。 For a client-side implementation, it means that a user will be able to alter those values.对于客户端实现,这意味着用户将能够更改这些值。 Your use case is about premium content so it's problematic.您的用例是关于优质内容的,因此存在问题。 To work around the problem you have to use an API Key with those parameters burn in it.要解决此问题,您必须使用带有这些参数的API 密钥 You won't be able to override them at search time.您将无法在搜索时覆盖它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM