仅在包含突出显示的匹配项时在搜索结果模板中显示属

时间:2016-04-30 04:42:15

标签: search search-engine algolia

我有几个属性设置为attributesToRetrieve。在我的模板中,虽然只显示了其中一些。大概是这样的:

<div id="results">
  <div>{{_highlightResult.attr1.value}}</div>
  <div>{{_highlightResult.attr2.value}}</div>
  <div>{{_highlightResult.attr3.value}}</div>
</div>

这样,属性将在任何情况下呈现,并且如果它们包含匹配的单词则突出显示。

现在我想添加另一个部分,其中可以显示所有其他属性,但仅当它们包含要突出显示的匹配单词时,例如:

<div id="results">
  <div>{{_highlightResult.attr_1.value}}</div>
  <div>{{_highlightResult.attr_2.value}}</div>
  <div>{{_highlightResult.attr_3.value}}</div>
<!-- 
The following div will be rendered and displayed only 
if any of these special attributes contain an highlighted word. 
Only an attribute containing a matched word will be displayed 
-->
  <div class="other-attr">
    {{_highlightResult.Long_SpecialAttr_1.value}}
    {{_highlightResult.SpecialAttr_2.value}}
    {{_highlightResult.SpecialAttr_3.value}}
  </div>
</div>

如评论中所述,只有当这些特殊属性中的任何一个包含突出显示的单词时,才会呈现和显示此部分,同时也只显示包含匹配单词的属性。

另外,你可以看到有一个Long_SpecialAttr_1,它是一个很长的文字属性,我想把它显示为一个片段属性。

为了给出一个更好的想法(也许),我想要为这个额外的部分实现的目标就像Google在每个搜索结果下面显示的那样,一种 text blob 文本省略号包含这些属性的标记词。

这可能吗?我正在使用algolia instasearch.js,谢谢!

更新

感谢@Jerska的答案,不幸的是,我的案例中没有一小段代码可用,特别是:

['highlight', 'snippet'].forEach(function (type) {
  data['_' + type + 'Result'].forEach(function (elt) {
    elt.display = elt.matchLevel !== 'none';
  });
});

在控制台中给我一个错误,说明data._snippetResult.forEach() is undefined。所以我用这个修改了那个位:

for(var el in d._snippetResult)
{
  // create new property with bool value, true if not "none"
  d._snippetResult[el].display = d._snippetResult[el].matchLevel !== 'none';
};

1 个答案:

答案 0 :(得分:4)

首先,为了在前进之前澄清索引的设置,Algolia还会在attributesToSnippet中突出显示属性。
另外,要对您的代码段属性进行省略,您可以设置snippetEllipsisText 因此,您可能希望在索引中使用这些设置:

attributesToHighlight: ['attr_1', 'attr_2', 'attr_3', 'SpecialAttr_2', 'SpecialAttr_3'],
attributesToSnippet: ['Long_SpecialAttr_1:3'], // Snippet should contain max 3 words
snippetEllipsisText: '…' // This is the utf-8 "Horizontal ellipsis" character

在前端,在instantsearch.js中,您可以在几乎任何窗口小部件上使用transformData参数,以便能够访问和/或修改传递给模板的数据。

在这个具体的例子中,我们想看看transformData.item on the hits widget

第一步是记录数据:

search.addWidget(
  instantsearch.widgets.hits({
    transformData: {
      item: function (data) {
        console.log(data);
        return data;
      }
    }
  })
);

这样你就可以看到那种反应:

_highlightResult: {
  attr_1: {
    value: 'lorem <em>ipsum</em> dolor <em>sit</em>',
    matchLevel: 'full',
    matchedWords: ['ipsum', 'sit']
  },
  attr_2: {
    value: 'lorem <em>ipsum</em> dolor',
    matchLevel: 'partial',
    matchedWords: ['ipsum']
  },
  attr_3: {
    value: 'lorem',
    matchLevel: 'none',
    matchedWords: []
  },
  // ...
},
_snippetResult: {
  Long_SpecialAttr_1: {
    value: 'lorem <em>ipsum</em> dolor …', // Let's assume Long_SpecialAttr_1 was equal to 'lorem ipsum dolor sit'
    matchLevel: 'full'
  }
}

不幸的是,这里的API有点不一致,因为你可以看到,snippeted属性没有突出显示属性的matchedWords属性。如果您真的需要信息,可以选择在attributesToSnippetattributesToHighlight设置。

但是,对于您的用例,我们只需要matchLevel。我们想要的是仅在matchLevel !== 'none'时显示元素。不幸的是,instantsearch.jstransformData的基础模板引擎并不具备很大的灵活性,因此您无法在模板中进行此比较。

解决方案可能是在transformData: { item: function (data) { ['highlight', 'snippet'].forEach(function (type) { var group = data['_' + type + 'Result']; for (var attr in group) { if (!group.hasOwnProperty(attr)) continue; var elt = group[attr]; elt.display = elt.matchLevel !== 'none'; }; }); data.displaySpecial = false || data._snippetResult.Long_SpecialAttr_1.display || data._highlightResult.SpecialAttr_2.display || data._highlightResult.SpecialAttr_3.display; return data; } }

中预先计算这些条件
<div id="results">
  <div>{{{_highlightResult.attr_1.value}}}</div>
  <div>{{{_highlightResult.attr_2.value}}}</div>
  <div>{{{_highlightResult.attr_3.value}}}</div>
<!-- 
The following div will be rendered and displayed only 
if any of these special attributes contain an highlighted word. 
Only an attribute containing a matched word will be displayed 
-->
  {{#displaySpecial}}
    <div class="other-attr">
      {{#_snippetResult.Long_SpecialAttr_1.display}}
        {{{_highlightResult.Long_SpecialAttr_1.value}}}
      {{/_snippetResult.Long_SpecialAttr_1.display}}

      {{#_highlightResult.SpecialAttr_2.display}}
        {{{_highlightResult.SpecialAttr_2.value}}}
      {{/_highlightResult.SpecialAttr_2.display}}

      {{#_highlightResult.SpecialAttr_3.display}}
        {{{_highlightResult.SpecialAttr_3.value}}}
      {{/_highlightResult.SpecialAttr_3.display}}
  </div>
  {{#displaySpecial}}
</div>

然后在模板中使用这些新属性:

{{{ ... }}}

(顺便说一下,为了呈现HTML,您应该使用{{...}}代替 qx.Class.define("q.Windows", { extend: qx.ui.window.Window, construct: function (){ this.base(arguments, "windows"); this.setWidth(600); this.setHeight(700); this.setResizable(true); var layout = new qx.ui.layout.Grow(); this.setLayout(layout); // ############################ CREATION SHAPE PAGE ######################## var tabView = new qx.ui.tabview.TabView(); this.add(tabView); // ############################ Page UN ######################## // ############################ Page UN ######################## var page1 = new qx.ui.tabview.Page("History", ""); page1.setLayout(new qx.ui.layout.Grow()); tabView.add(page1); // ############################ Backgroung page ######################## var group1 = new qx.ui.groupbox.GroupBox(this.tr("")); group1.setLayout(new qx.ui.layout.Grow()); // ############################ Introduction ######################### var htmlp1 = '<p align ="justify"> For more than 50 years hadron electromagnetic form factors are considered fundamental quantities for non point-like particles. They parametrize the internal structure of hadrons. </p><br> <p> <img src="images/proton_neutron.jpg" width="140" height="90" border="0" alt="CNRS" style="margin: 0px 15px 15px 0px; float: left;" /> <br>' + '<strong> Nucleons </strong>' + '<br><p align ="justify">This database collects all data and their references in the scattering (space-like) and in the annihilation (time-like) region, as they were published in the original articles. Experiments and theoretical developments are ongoing. Space-like measurements are based on unpolarized (Rosenbluth separation) and polarized (Akhiezer-Rekalo method) electron elastic scattering off protons and, for neutron, on electron scattering off light nuclei. In the time-like region the reactions e⁺e⁻→ pp̄ (accompanied or not by initial state radiation) and pp̄ → e⁺e⁻ allow to extract form factors relying on a precise angular distribution.</p>'; var embedp1 = new qx.ui.embed.Html(htmlp1); group1.add(embedp1); // ############################ Nucleon ######################### page1.add(group1); // ############################ Page DEUX ######################## // ############################ Page DEUX ######################## var page2 = new qx.ui.tabview.Page("Computation", ""); page2.setLayout(new qx.ui.layout.Grow()); tabView.add(page2); // ############################ Backgroung page ######################## var group2 = new qx.ui.groupbox.GroupBox(this.tr("")); group2.setLayout(new qx.ui.layout.VBox(10)); // ############################ Objectif ######################### var fs1 = new qx.ui.groupbox.GroupBox(this.tr("")); fs1.setLayout(new qx.ui.layout.Grow()); var label = new qx.ui.basic.Label(); label.setValue("This is a qooxdoo application skeleton which is used as a template. The 'create-application.py' script (usually under tool/bin/create-application.py)will use this and expand it into a self-contained qooxdoo application which can then be further extended. Please refer to the script and other documentationfor further information."); label.setRich(true); // var embedp2 = new qx.ui.embed.Html(htmlp2); fs1.add(label); group2.add(fs1); var spacer = new qx.ui.core.Spacer(); group2.add(spacer, {flex: 1}); // ############################ Simul ######################### var fs = new qx.ui.groupbox.GroupBox(this.tr("Choice")); fs.setLayout(new qx.ui.layout.Grow()); //Setup of the checkboxes var mainLayout = new qx.ui.layout.Grid(0, 0); mainLayout.setSpacing(10); var container = new qx.ui.container.Composite(mainLayout); container.setPadding(20); var slp = new qx.ui.form.CheckBox("Space Like Protons"); var tlp = new qx.ui.form.CheckBox("Time Like Protons"); var sln = new qx.ui.form.CheckBox("Space Like Neutrons"); var tln = new qx.ui.form.CheckBox("Time Like Neutrons"); container.add(slp, {row: 2, column: 1}); container.add(tlp, {row: 2, column: 2}); container.add(sln, {row: 1, column: 1}); container.add(tln, {row: 1, column: 2}); var btOk = new qx.ui.form.Button("OK"); var checkBoxes = [slp, tlp, sln, tln]; container.add(btOk, {row: 3, column: 2}); fs.add(container); group2.add(fs); // Creation of the function linked to the button OK btOk.addListener("execute", function (e){ var cbs = checkBoxes; var count = 0; var str = ""; for (var i = 0; i < cbs.length; i++) { if (cbs[i].getValue()) { count++; str += (cbs[i].getLabel() + ", "); } } if (count > 0) { str = str.substring(0, str.length - 2); alert("You want" + str); } else { alert("No choice"); } }); page2.add(group2); } }); ,我已经在这里替换了它们。