以前,我曾经写
MyCollection.find({ $text: { $search: 'foo' } }, {
fields: {
score: { $meta: "textScore" }
},
sort: {
score: { $meta: "textScore" }
}
});
但是,现在我得到一个错误
I20180926-18:26:08.708(-4)? Exception from sub mysubscription id ZeSWJcoghED3t6Eq6 Error: Exception while polling query {"collectionName":"my-collection","selector":{"$text":{"$search":"foo"}},"options":{"transform":null,"limit":25,"sort":{"score":{"$meta":"textScore"}}}}: must have $meta projection for all $meta sort keys
I20180926-18:26:08.709(-4)? at PollingObserveDriver._pollMongo (packages/mongo/polling_observe_driver.js:165:11)
I20180926-18:26:08.709(-4)? at Object.task (packages/mongo/polling_observe_driver.js:93:12)
I20180926-18:26:08.710(-4)? at Meteor._SynchronousQueue.SQp._run (packages/meteor.js:987:16)
I20180926-18:26:08.710(-4)? at packages/meteor.js:964:12
在尝试查找更多信息时,this answer提到fields
参数需要包含在投影中,例如
collection.find({
$text:
{
$search: filter,
$caseSensitive: false,
$diacriticSensitive: true
}
})
.project({ score: { $meta: "textScore" } })
.sort({score:{$meta:"textScore"}})
但是,流星没有没有.project
方法。
有什么解决方案?
答案 0 :(得分:1)
下面有一个已创建的mini-repro指南。它显示了如何像最初报告的那样执行(索引)文本搜索以引发错误。
因此,人们可以假设错误的来源,例如,向Meteor 1.7+ / Mongo 3.6+的移植或代码中的错误。迁移很有可能包含原因,因为最近在论坛和SO上发布了许多有关升级到1.7的问题的帖子。
因此,这是一份简短的清单,列出了可能出了什么问题:
db.createIndex
时使用了较早的Mongo以及以前的文本索引。我还没有发现任何破坏向后兼容性的信息,但这可能是原因。如果您是开发人员,则可以执行db.collection.getIndexes()
轻松地进行验证。例如,下面创建的repro项目具有以下输出:获取当前索引:
meteor:PRIMARY> db.texts.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "meteor.texts"
},
{
"v" : 2,
"key" : {
"_fts" : "text",
"_ftsx" : 1
},
"name" : "text_text",
"ns" : "meteor.texts",
"weights" : {
"text" : 1
},
"default_language" : "english",
"language_override" : "language",
"textIndexVersion" : 3
}
]
Mongo.Collection.rawCollection
来实现对集合的本机操作。请注意此对扩展到integrate native Mongo operations into your Meteor environment 为了验证它是否正在与新项目一起工作(发布METEOR@1.7.0.5
),您可以复制以下步骤:
$ meteor create metasearch
$ cd metasearch
$ meteor npm install --save faker
$ meteor
Texts
中创建一个名为/imports/Texts.js
的集合:import { Mongo } from "meteor/mongo"
export const Texts = new Mongo.Collection('texts')
/server/main.js
:import { Meteor } from 'meteor/meteor'
import { Texts } from '../imports/Texts'
Meteor.startup(() => {
import { lorem } from 'faker'
for (let i = 0; i < 5; i++) {
Texts.insert({
title: lorem.words(),
text: lorem.text()
})
}
})
Meteor.publish('search', function searchpub (filter) {
const cursor = Texts.find({
$text: {
$search: filter,
$caseSensitive: false,
$diacriticSensitive: false,
}
}, {
fields: {
score: {$meta: 'textScore'},
},
sort: {
score: {$meta: 'textScore'},
},
})
// fallback if cursor is undefined
if (cursor && cursor.count && cursor.count() >= 0) {
return cursor
} else {
this.ready()
}
})
如您所见,它使用了最初发布时的默认“查询,投影和在一个文档中排序”结构。
/client/main.js
代码:import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import './main.html';
import {Texts} from '../imports/Texts'
Template.hello.onCreated(function helloOnCreated() {
// counter starts at 0
this.counter = new ReactiveVar(0);
const instance = this
instance.autorun(() => {
const cursor = instance.subscribe('search', 'dolor') // use a word, that often occurs
if (cursor.ready()) {
console.log(Texts.find().fetch())
}
})
});
// ... rest of the file
$ meteor mongo
$ db.texts.createIndex({text:"text"})
输出应类似于:
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1,
"operationTime" : Timestamp(1538031016, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1538031016, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
与此同时,Meteor.startup
引起的插入应该可以创建少量的文档进行搜索,但是它们可能尚未添加到索引中。
您可以取消正在运行的实例,然后再次重新启动几次(或增加启动时要插入的文档数量),以获得大量匹配项。
默认情况下,在localhost:3000
上运行时,您应该获得类似以下的输出:
Array (51) […]
0: {…}
_id: "n2WhMskCXBm7ziZea"
score: 1.0416666666666667
text: "Dolor at sed et dolorem tenetur a dolore voluptate incidunt. Rerum corrupti officia aut tenetur nisi officiis voluptas soluta. Fugiat eos sed expedita inventore. Esse cupiditate qui. Facere dolor quisquam ipsa a facere praesentium. Aut sunt mollitia dolore tenetur."
title: "quia est fuga"
<prototype>: Object { … }
1: {…}
_id: "QjAcZQLTH8Mc3jDzS"
score: 1.0110294117647058
text: "Sequi dolores omnis sequi consequatur laborum et asperiores. Accusantium repellat magnam est aut suscipit enim iure. Qui qui aut cupiditate necessitatibus commodi qui quia. Ut tempore autem provident maiores cumque necessitatibus dolores accusantium. Nostrum ut ut sunt adipisci qui consequuntur explicabo voluptas. Minima praesentium sunt facere doloribus non at dolor dolore est."
title: "est explicabo omnis"
<prototype>: Object { … }