如何使用Micronaut在mongoDB中创建TextFree搜索

问题描述

我正在使用反应式MongoDb,并尝试实现基于重量的自由文本搜索

implementation("io.micronaut.mongodb:micronaut-mongo-reactive")

在POJO下方

public class Product {
    @BsonProperty("_id")
    @BsonId
    private ObjectId id;
    private String name;
    private float price;
    private String description;
}

尝试了这个简单的例子

public Flowable<List<Product>> findByFreeText(String text) {
    LOG.info(String.format("Listener --> Listening value = %s",text));
    Flowable.fromPublisher(this.repository.getCollection("product",List.class)
            .find(new Document("$text",new Document("$search",text)
                    .append("$caseSensitive",false)
                    .append("$diacriticSensitive",false)))).subscribe(item -> {
                System.out.println(item);
            },error -> {
                System.out.println(error);
            });
    return Flowable.just(List.of(new Product()));
}

我认为这不是实施自由文本搜索的正确方法。

解决方法

起初,您不需要将FlowableList中的Product一起使用,因为Flowable可以管理的值多于Single。因此,拥有Flowable<Product>就足够了。然后,您可以简单地从Flowable方法返回find实例。

然后可以像这样实现文本搜索:

public Flowable<Product> findByFreeText(final String query) {
    return Flowable.fromPublisher(repository.getCollection("product",Product.class)
        .find(new Document("$text",new Document("$search",query)
                .append("$caseSensitive",false)
                .append("$diacriticSensitive",false)
        )));
}

然后由方法的使用者决定如何预订结果Flowable。在控制器中,您可以直接返回Flowable实例。如果您需要在代码中的某处使用它,可以执行subscribe()blockingSubscribe()等等。

您当然可以通过JUnit进行如下测试:

@MicronautTest
class SomeServiceTest {
    @Inject
    SomeService service;

    @Test
    void findByFreeText() {
        service.findByFreeText("test")
            .test()
            .awaitCount(1)
            .assertNoErrors()
            .assertValue(p -> p.getName().contains("test"));
    }
}

更新:您可以通过在 logback.xml (Micronaut使用Logback作为默认日志记录框架)中设置日志配置文件来调试与MongoDB的通信:

<configuration>
    ....
    <logger name="org.mongodb" level="debug"/>
</configuration>

然后您将在日志文件中看到它:

16:20:21.257 [Thread-5] DEBUG org.mongodb.driver.protocol.command - Sending command '{"find": "product","filter": {"$text": {"$search": "test","$caseSensitive": false,"$diacriticSensitive": false}},"batchSize": 2147483647,"$db": "some-database"}' with request id 6 to database some-database on connection [connectionId{localValue:3,serverValue:1634}] to server localhost:27017
16:20:21.258 [Thread-8] DEBUG org.mongodb.driver.protocol.command - 16:20:21.258 [Thread-7] DEBUG org.mongodb.driver.protocol.command - Execution of command with request id 6 completed successfully in 2.11 ms on connection [connectionId{localValue:3,serverValue:1634}] to server localhost:27017

然后,您可以从日志中复制命令并在MongoDB CLI中尝试使用该命令,也可以安装MongoDB Compass,在其中进行更多操作,并查看命令是否正确。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...